Compare commits

...

268 Commits

Author SHA1 Message Date
Vlad Frangu
8e374aa8e3 chore(create-discord-bot): release create-discord-bot@4.0.0 (#10947)
* chore(create-discord-bot): release create-discord-bot@4.0.0

* chore(ci): handle identical deploy to create-discord-app

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-06-22 21:39:09 +00:00
Jiralite
cbb20566c5 feat(webhook): Support with_components (#10945)
feat: support `with_components`
2025-06-22 09:42:01 +00:00
Vlad Frangu
127bb59638 chore: bump discord.js across create-discord-x templates (#10935) 2025-06-18 09:46:34 +00:00
Crytek1012
2852a529cf docs: update param wording for consistency (#10930) 2025-06-12 10:33:01 +00:00
Danial Raza
4e0beff17b types(ClientEventTypes): add missing guildSoundboardSoundsUpdate (#10928) 2025-06-08 15:01:47 +00:00
Almeida
8e03af6eaf feat: update @types/node to v22 (#10926) 2025-06-07 13:21:57 +00:00
Qjuh
9708717204 fix(api-extractor): links including entrypoints (#10924) 2025-06-07 13:17:29 +02:00
Almeida
db8c1d3edb fix: background on pages with little content (#10925) 2025-06-07 13:16:58 +02:00
Snazzah
d40ceedad4 feat(voice): use voice gateway v8 (#10918)
* feat(voice): use voice gateway v8

* docs: small typo

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-06-02 17:38:50 +00:00
Almeida
e094faf225 docs: add missing, fix existing (#10842)
* docs: add missing, fix existing

* refactor: new stuff

* fix: requested changes

* fix: use `@link` for `@mixes`

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* chore: disable bad eslint rule

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-06-02 17:35:43 +00:00
Qjuh
8d50e92516 chore: ignore eslint-config-neon change commit in blame (#10919) 2025-06-02 19:32:07 +02:00
Qjuh
727c7e225f docs: don't generate all sub-package docs for /next (#10916) 2025-06-02 19:24:32 +02:00
Qjuh
b03c65c34c refactor: using eslint-config-neon on mainlib (#10876)
* refactor: using eslint-config-neon on mainlib

* fix: lint

* fix: lint

* fix: the way we lint

* chore: lint some more

* fix: more lint changes

* fix: type tests

* chore: port eslint rule

* refactor: lintstaged doesn't need this

* fix: eslint was a bit too eager

* fix: forgot Client

* Apply suggestions from code review

Co-authored-by: Almeida <github@almeidx.dev>

* chore: more lint fixes

* fix: remove useless Boolean()

* fix: get docs back

* fix: snowflake docs

* refactor: don't use typescript lint rules

* fix: code review

* fix: tidy up disabled rules

* chore: code review

* chore: code review

* chore: code review

* fix: consistent spacing in typings

* fix: tests

* fix: unsort ErrorCodes

* chore: get comments back

* Update packages/discord.js/src/client/websocket/handlers/THREAD_LIST_SYNC.js

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

* fix: remove unused parameter

* fix: merge messed up types

* fix: more type mess from merge

* fix: generate script for ActionsManager

* fix: code review

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

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

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

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

* fix: replace is faster, unicorn is wrong

* fix: consistency

* fix: delete obsolete file

* fix: minor nit in test file

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-06-02 17:23:40 +00:00
Amgelo563
ef2c1bfa77 fix(Emoji): remove incorrect nullables, add ApplicationEmoji#available (#10913)
* types: remove unintended nullables from app and base guild emojis

* feat: add ApplicationEmoji#available

* types(BaseGuildEmoji): fix incorrect JSDoc type for BaseGuildEmoji#name

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* types(Emoji): switch from # to . for property deprecation links

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* fix: remove default nulls in app emoji constructor on non-nullables

* types(Emoji): replace raw data type pre 78d512c

* types(Emoji): switch to ImageURLOptions for imageURL()

Re-applies changes from #10613

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* types(Emoji): remove deprecated `url` props types and descriptions

Added by mistake in PR that used to target v14

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

* refactor(Emoji): wording and formatting changes to prop descriptions

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

* refactor(Emoji): missed wording and formatting change to prop descriptions

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

* fix(Emoji)!: remove non present Emoji#url from typings

* fix(Emoji): re-apply emoji url types from 2c35084

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-30 19:06:06 +00:00
iCrawl
762bbc6525 refactor(website): switch to dynamic only 2025-05-30 02:29:15 +02:00
Jiralite
2c35084ecd feat!: Support animated WebP (#10911)
* feat: support animated WebP

* refactor: change the rest

* fix: remove redundant code
2025-05-27 10:18:30 +01:00
Almeida
78d512c347 docs: export all visible symbols (#10760)
* docs: export all visible symbols

* fix: discord.js except raw

* refactor: remove raw data types

* docs: add back discord.js tsdoc file

* refactor: remove underscores

* fix: merge

* docs(RPCRedis): make `promises` as internal

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-26 17:41:08 +00:00
Jack
c1f5bb2fba fix(InteractionResponses): Optional parameter for update() (#10797)
* fix: 🔧 don't error out if no options are provided

This commit stops calls to `options.withResponse`, etc erroring out when `interaction.update();` is called alone with no params.

* tweak: ⚙️ make options optional on typedef

* fix: 🔧 update index.d.ts

Update types to allow options to be optional

* types: add tests

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-05-25 12:01:35 +00:00
Qjuh
8605fc81fa fix(api-extractor): include entrypoint in links (#10902)
* fix(api-extractor): include entrypoint in links

* chore: prettier
2025-05-18 20:36:17 +02:00
iCrawl
33d8619a4e feat(website): include loading indicators when data is fetching 2025-05-16 00:19:17 +02:00
iCrawl
576443c29a fix(website): don't crash if no version was found 2025-05-15 22:05:38 +02:00
iCrawl
c92a8c27a2 fix: sidebar behaviour when switching package/version 2025-05-15 17:11:47 +02:00
Qjuh
14e226b72b fix(website): remove several obsolete special handling of dtypes (#10898)
* fix(website): remove several obsolete special handling of dtypes

* fix: reduce hardcoded places

* chore: api-extractor.json setting mainEntryPointName
2025-05-13 20:40:41 +02:00
iCrawl
aa533efe26 feat: discord-api-types on docs 2025-05-13 01:33:48 +02:00
Qjuh
b3db92edfb feat(api-extractor): support multiple entrypoints (#10829)
* feat(api-extractor): support multiple entrypoints

* chore: initial support in generateSplitDocumentation

* chore: bring in line with upstream

* refactor: multiple entrypoints in scripts

* fix: split docs

* feat: website

* fix: docs failing on next

* fix: don't include dtypes for now

* refactor: don't fetch entrypoint if there is none

---------

Co-authored-by: iCrawl <buechler.noel@outlook.com>
2025-05-12 23:48:41 +02:00
Qjuh
4f5e5c7c14 feat: components v2 (#10847)
* feat: components v2

* fix: tests

* fix: merge

* fix: lint

* Update packages/discord.js/src/util/Components.js

* fix: forward-port fixes from v14

* fix: getter

* fix: missing UnfurledMediaItem#toJSON()

* fix: find interactive component in container

* docs(APIMediaGalleryItem): Correct tag

* fix: forward port

* Apply suggestions from code review

Co-authored-by: Danial Raza <danialrazafb@gmail.com>

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Danial Raza <danialrazafb@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-11 20:46:09 +00:00
Danial Raza
2c21de68f3 refactor: remove registerEvents function (#10877)
* refactor: remove `registerEvents` function

* refactor: use try-catch

* fix: missing `await`
2025-05-11 12:21:13 +00:00
Jiralite
4f6fedfb1f fix(ChannelManager): Remove threads from cache upon deletion (#10883)
* fix(ChannelManager): remove threads from cache upon deletion

* refactor: loop over thread ids

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-09 11:06:35 +00:00
Danial Raza
c4cd6ea637 feat: soundboard forward port (#10859)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-09 07:43:40 +00:00
Qjuh
f6da9495ed fix(website): link to enum members in search index (#10875)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-07 21:26:43 +00:00
Almeida
f686c83b18 fix: codeblock background and other mobile issues (#10892)
* fix: codeblock background

* fix: horizontal scroll on properties

* fix: badge text wrapping

* fix: wrap overload tab list
2025-05-07 23:17:09 +02:00
Jiralite
436784f945 perf(Components): Hash table (#10890)
refactor(Components): hash table

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-07 21:14:58 +00:00
Jiralite
320e3a6246 fix(PartialGroupDMChannel): Prevent undefined values (#10889)
fix(PartialGroupDMChannel): prevent `undefined` values

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-07 16:45:47 +00:00
Almeida
026440c256 build: exclude type tests from pack (#10886)
* build: exclude type tests from pack

* fix: requested changes

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-07 16:32:11 +00:00
Jiralite
432cdbe88a refactor(Client): Remove with_expiration query parameter (#10800)
refactor(Client): remove `with_expiration`

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-06 14:24:12 +00:00
brynpttrsn
c48cc74c4b fix: syntaxhighlighter fill scrollbar width (#10887)
Co-authored-by: Bryan P. <bryanp.@iMac.lan>
2025-05-06 10:48:05 +02:00
Qjuh
6efdf3b901 fix(website): link to external constructors (#10869)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-05 07:15:53 +00:00
Danial Raza
4acb71496f chore: update create-discord-bot dependencies (#10878)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-05-05 07:00:35 +00:00
Almeida
4646a74565 build: fix deploy failure (#10885) 2025-05-05 06:59:14 +00:00
Almeida
bae1b4c17d docs: fix missing type (#10882) 2025-05-04 09:12:18 +00:00
Almeida
28e5dd2e80 fix: padding on codeblocks (#10881) 2025-05-03 22:57:04 +02:00
Qjuh
65f41bea96 fix(website): constructors show on too many items (#10880) 2025-05-03 20:25:00 +00:00
Qjuh
75179fbf9f chore: bump zlib-sync to 0.1.10 (#10873) 2025-05-01 20:43:44 +00:00
iCrawl
696d8339a3 docs: use correct base url 2025-04-28 02:37:42 +02:00
iCrawl
c3c12fb78b docs: redirect to guide 2025-04-28 02:31:29 +02:00
Noel
2184085fda docs: guide setup (#10862) 2025-04-28 02:23:27 +02:00
Vlad Frangu
291012c18a chore: forward-port release metadata from side branches (#10848)
* chore(rest): forward-port release metadata from v14 branch

* chore(formatters): forward-port release metadata from builders/v1 branch

* chore(builders): forward-port release metadata from builders/v1 branch

* chore(core): forward-port release metadata from v14 branch

* chore(ws): forward-port release metadata from v14 branch

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-27 18:30:38 +00:00
Qjuh
d32aacd14c feat(website): show examples on constructors (#10856)
* feat(website): show examples on constructors

* fix: lint

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-27 00:48:18 +00:00
Almeida
a4f3a2574d ci: update list of packages in codecov uploads (#10846)
* ci: update list of packages in coverage upload

* build: remove test dependencies

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-27 00:45:54 +00:00
Almeida
8f375275ca fix: message builders (#10802)
* fix: message builders

- Added `clearParse`, `clearRoles`, and `clearUsers` methods to the `AllowedMentionsBuilder`, since passing an empty array and omitting the these fields behave differently
- Strictened assertions
- Removed `AttachmentBuilder#clearId`, as it is a required field
- Added missing `MessageBuilder#setEmbeds`
- Added missing `MessageReferenceBuilder#setFailIfNotExists`
- Improve/fix documentation
- Consistency™️

* fix: updater functions return type

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-25 20:52:00 +00:00
Danial Raza
d81b4be2cd feat: add soundboard (#10590)
* feat: add soundboard

* types(PartialSoundboardSound): add `available`

* feat(VoiceChannelEffect): add `soundboardSound` getter

* types: improve return types

* docs: requested changes

* feat: support multiple audio file types

* types(GuildSoundboardSoundCreateOptions): add `contentType`

* types: add default and guild soundboard sound

* fix: requested changes

* docs: use `@fires` tag

* docs: remove misleading tag

* chore: requested changes and missing things

* feat: add send soundboard sound options
2025-04-25 19:43:17 +00:00
Naiyar
8e4e319c24 feat: entry-point command (#10640)
* feat: entry point command

* chore: update tests

* chore: suggested change

* chore: suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* chore: suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* chore: suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* chore: suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* chore: suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* chore: remove extra info closing tag

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-24 19:55:30 +00:00
Qjuh
5a4de953fa fix: generateSplitDocumentation for external docs on main (#10827)
* fix: generateSplitDocumentation for external docs on main

* fix: remove console.log

* chore: apply suggestion

Co-authored-by: Almeida <github@almeidx.dev>

* fix: mixes tag

* chore: docs include collection

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-24 19:19:52 +00:00
Sammy
891fe277bf fix(builders): export container component (#10844) 2025-04-24 17:13:34 +00:00
Vlad Frangu
abc5d99ce8 feat: components v2 in builders (#10788)
* feat: thumbnail component

* chore: just a temp file to track remaining components

* feat: file component

* feat: section component

* feat: text display component

* chore: bump alpha version of dtypes

* chore: simplify ComponentBuilder base type

* feat: MediaGallery

* feat: Section builder

* chore: tests for sections

* chore: forgot you

* chore: docs

* fix: missing comma

* fix: my bad

* feat: container builder

* chore: requested changes

* chore: missed u

* chore: type tests

* chore: setId/clearId

* chore: apply suggestions from code review

* chore: unify pick

* chore: some requested changes

* chore: tests and small fixes

* chore: added tests that need fixing

* fix: tests

* chore: cleanup on isle protected

* docs: remove locale

* chore: types for new message builder

* chore: fix tests

* chore: attempt 1 at message builder assertions

* chore: apply suggestions

* Update packages/builders/src/messages/Assertions.ts

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

* Update packages/builders/src/components/v2/Thumbnail.ts

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

* fix: tests

* chore: fmt

* Apply suggestions from code review

Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>

* chore: fix pnpm lockfile revert

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>
2025-04-23 17:29:15 +00:00
Vlad Frangu
42ce116226 chore(deps): bump discord-api-types (#10841)
* chore(deps): bump discord-api-types

* chore: tests

* chore: tests 2

* chore: replace ImageSize type with dtypes type
2025-04-22 17:12:34 +00:00
柚子Youzi
8f35dfd039 docs(readme): add import statement for pure REST usage to align with other examples (#10838)
* docs(readme): add import statement for pure REST usage to align with other examples

Added missing `import` statements in the "Independent REST API Usage" section to maintain consistency with the rest of the README examples.  
This change also ensures that the usage of `@discordjs/core` reflects a REST-only setup by importing from `@discordjs/core/http-only`, which avoids dependency issues like `Can't resolve 'zlib-sync'`.

* fix: standardize import quotes in README.md

* style: organise imports

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-04-20 14:10:24 +00:00
Qjuh
92e07c8f7f types: add missing BaseMessageCreateOptions (#10833)
* types: add missing BaseMessageCreateOptions

* build: trigger tests

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: almeidx <github@almeidx.dev>
2025-04-18 16:46:55 +00:00
Qjuh
feec5efe45 fix: don't set ready status twice (#10807)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-17 18:11:24 +00:00
Danial Raza
57c3da2e8e docs(ApplicationCommand): incorrect method in example (#10837) 2025-04-16 17:26:28 +00:00
Almeida
5c0b714557 fix: structure imports on windows (#10835) 2025-04-13 19:45:11 +00:00
Almeida
f0ea40586b build: bump discord-api-types to 0.37.120 (#10832)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-11 08:26:23 +00:00
iCrawl
056c691281 ci: update pnpm version when building main 2025-04-11 01:56:42 +02:00
iCrawl
8ce8f7ff46 ci: fix upload to database 2025-04-11 01:09:24 +02:00
iCrawl
e22a7bb505 ci: upload docs to cf 2025-04-11 00:55:57 +02:00
Qjuh
74110b3e7d fix(website): add type to variables (#10779)
* fix(website): add type to variables

* chore: apply suggestion

* chore: lint
2025-04-10 22:44:35 +02:00
Almeida
53ba3b6016 feat(BaseInteraction): add attachmentSizeLimit (#10830)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-10 20:41:52 +00:00
Noel
2e3bc69602 refactor: website facelift (#10823) 2025-04-10 22:02:37 +02:00
Almeida
1fe53c7ca2 chore: move pnpm settings to pnpm-workspace.yaml (#10828)
* chore: move pnpm settings to pnpm-workspace.yaml

* chore: remove contentlayer remains

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-10 17:42:05 +00:00
Jiralite
3b76c7072d build: Bump Undici to 7.8.0 (#10831)
build: bump Undici
2025-04-10 13:40:46 +00:00
Danial Raza
d93a52c1dd chore: remove has PR label (#10820)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-04-07 16:22:31 +00:00
Jiralite
2e99c26c6d build: allowAny instead of allowedAny (#10825) 2025-04-07 05:07:45 +00:00
Noel
f580de8025 chore: upgrade deps (#10824) 2025-04-05 13:18:56 +02:00
Danial Raza
432aba3df7 types(ModalSubmitFields): fix fields type (#10816)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-30 11:45:37 +00:00
Almeida
646ecae47f fix(Message): forwarded messages are not crosspostable (#10821)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-29 08:17:51 +00:00
Almeida
93f2ba0fc8 fix(PollAnswer): only define _emoji property once (#10811)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-27 18:05:05 +00:00
Jacob Morrison
3234fc6b3b fix(Poll): ensure this.answers is set before we reference it (#10809)
* Ensure 	his.answers is set sooner if it's null during a patch

* Move data.answers block up as well to ensure the patched answers are set

* Ensure collection is set in constructor instead

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-27 18:01:05 +00:00
Almeida
73f2ef9c87 fix: all shards spawning on shard 0 with sharding manager (#10814) 2025-03-22 20:17:14 +00:00
Jiralite
4d19426810 fix(textInput): Value must be at least 1 character in length (#10805)
fix(textInput): value must be at least 1 in length
2025-03-17 15:31:44 +00:00
Muhammad Nizamuddin Aulia
79b79b6a44 fix(create-discord-bot): register command files in subdirectories (#10775)
* feat(create-discord-bot): add user command in utility subdirectory

* fix(create-discord-bot): command files in the subdirectory were skipped

* fix(create-discord-bot): fix command files in subdirectory were skipped in Deno template

* fix: minor fix

* fix: lint

* refactor: suggested changes

revert: unrelated change

---------

Co-authored-by: almeidx <github@almeidx.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-03-16 18:38:48 +00:00
Jiralite
eabcc52594 refactor(constants): Update guide URL (#10803)
refactor(constants): update guide URL
2025-03-16 17:18:25 +00:00
Qjuh
a151424261 fix(website): correctly link type parameters in docs (#10801) 2025-03-15 22:39:29 +00:00
Denis-Adrian Cristea
09beb8a6a0 feat: message builder (#10793)
* feat: attachment builder

* feat: message builder

* chore: nits

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

* fix: nonce assertion

* chore: strip bad method

* chore: nit

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

* chore: nits

* chore: address final review

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-03-14 08:09:15 +00:00
Almeida
ab6a69401e docs: remove hardcoded locale from links (#10794)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-07 21:23:42 +00:00
Jiralite
12638cd43c fix(embed): Allow attachment protocols for thumbnails and images (#10795)
fix(embed): allow attachment protocols for thumbnails and images

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-07 20:19:14 +00:00
Jiralite
c78407e751 fix(GuildMemberManager): Ensure empty object for fetching many guild members (#10796)
fix(GuildMemberManager): pass empty object for fetching many
2025-03-07 20:15:54 +00:00
Danial Raza
e273afbb93 feat: override groupBy to return Collection (#10791)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-03-05 20:19:20 +00:00
Danial Raza
b7e334e74a feat(Webhook): allow setting withComponents (#10792)
* feat(Webhook): allow setting `withComponents`

* docs: remove brackets

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

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-03-05 19:08:22 +00:00
Denis-Adrian Cristea
0f89353443 refactor!: remove discord.js builders (#10529)
BREAKING CHANGE: Removed all builder extensions within discord.js
2025-03-05 14:34:49 +02:00
Denis-Adrian Cristea
28a945069f fix(ContextMenuCommandBuilder): allow emoji in name (#10790)
* fix(ContextMenuCommandBuilder): allow emoji in name

* test: add emoji from 16.0

https://emojipedia.org/fingerprint

* chore: non rule-breaking regex

* feat: use simplified regex

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* style: prettier

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
2025-03-05 12:15:54 +00:00
Almeida
d1f56ffb2a fix: poll builders (#10783)
* fix: poll builders

- Fixed validations
- Added missing documentation
- Removed redundant code
- Consistency™️

* fix: tests

* feat: missing answers test
2025-03-01 14:57:00 +00:00
TÆMBØ
88bfeaab22 feat: PollBuilder (#10324)
* Add PollBuilder

* Add exports

* Update typings

* Update validations

* Use correct enum validator method

* Fix assertion, formatting

* Add tests

* Fix assertion

* Add JSDoc, format

* Make requested changes

* Remove unnecessary blank import

* Add support for PollBuilder in mainlib discord.js

* Add types, fix formatting

* Correct typings & assertions for poll answer emojis

* Improve typings readability

* Add JSDoc typings for overrides

* Add types for using PollBuilder in message payload

* Add tests, allow passing Emoji instance to emoji option

* Fix formatting

* Update max poll duration

* refactor: implement builders v2 pattern
2025-02-28 10:07:27 +00:00
Danial Raza
b6fda781c8 refactor: remove parameter reassignment (#10715)
* refactor: remove parameter reassignment

* refactor: requested changes

Co-authored-by: Almeida <github@almeidx.dev>

* chore: requested changes

Co-authored-by: Qjuh <Qjuh@users.noreply.github.com>

* chore: requested changes

* refactor: destructure in parameters

Co-authored-by: Almeida <github@almeidx.dev>

* refactor: apply suggested changes

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Qjuh <Qjuh@users.noreply.github.com>
2025-02-26 15:31:29 +00:00
Almeida
bb6767113f feat: re-emit REST debug logs (#10782) 2025-02-25 06:20:10 +00:00
Jiralite
1054f4abce refactor(PackageSelect): Redirect to stable (#10778)
refactor(PackageSelect): redirect to stable

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-02-23 19:13:16 +00:00
Almeida
c429cc112b types(ShardClientUtil): remove count and ids (#10780) 2025-02-23 16:13:59 +00:00
Almeida
a1d19b909a refactor!: remove polyfillDispose (#10776)
BREAKING CHANGE: The `polyfillDispose` function has been removed
2025-02-22 00:52:06 +00:00
Danial Raza
ed55c029d6 fix(MessagePayload): preserve existing flags when editing (#10765)
* fix(MessagePayload): preserve existing flags when editing

* refactor: request changes

* fix: missing `.bitfield`
2025-02-21 15:17:33 +00:00
Danial Raza
cbb33ecdac types(InteractionCallbackResponse): add missing InGuild generic (#10767)
Co-authored-by: TÆMBØ <TAEMBO@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-02-21 15:11:07 +00:00
Naiyar
c4fbe89f48 fix(GuildChannelManager): properly resolve avatar for createWebhook (#10772)
fix(GuildChannelManager): properly resolve avatr for createWebhook
2025-02-21 11:14:38 +00:00
TÆMBØ
0e7bdb0728 feat!: create forwards and add ChannelManager#createMessage() (#10559)
BREAKING CHANGE: `MessageCreateOptions` no longer accepts `forward` or `reply`. Use `messageReference` instead.

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-02-20 21:53:52 +00:00
Vlad Frangu
19d48f6d6c feat: print out support for aes-256-gcm in native node:crypto (#10764) 2025-02-19 20:59:17 +00:00
Kevin
e3e3c212bd feat: polls overhaul (#10328)
* feat(Managers): add PollAnswerVoterManager

* feat(Partials): make Polls partial-safe

* types: add typings

* chore: add tests

* fix: use fetch method in manager instead

* chore: add tests for manager

* feat: add partial support to poll actions

* style: formatting

* fix: change all .users references to .voters

* refactor: add additional logic for partials

* fix: actually add the partials

* fix: fixed issue where event does not emit on first event

* fix: align property type with DAPI documentation

* fix: resolve additional bugs with partials

* typings: update typings to reflect property type change

* fix: tests

* fix: adjust tests

* refactor: combine partials logic into one statement

* docs: mark getter as readonly

* refactor: apply suggestions

Co-authored-by: Almeida <github@almeidx.dev>

* refactor(Actions): apply suggestions

* refactor(PollAnswerVoterManager): apply suggestions

* refactor(Message): check for existing poll before creating a poll

* refactor(Polls): apply suggestions

* revert(types): remove unused method from Poll class

* refactor(Actions): consolidate poll creation logic into action class

* refactor(PollAnswerVoterManager): set default for fetch parameter

* refactor(Message): apply suggestion

* fix: remove partial setter

* refactor(Polls): apply suggestions

* types: apply suggestions

* refactor: remove clones

* docs: spacing

* refactor: move setters from constructor to _patch

* types: adjust partials for poll classes

* test: add more tests for polls

* refactor: move updates around, more correct partial types

* fix: handle more cases

* refactor: requested changes

* fix: missing imports

* fix: update imports

* fix: require file extensions

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
2025-02-15 20:20:54 +00:00
Qjuh
44b0f7dd99 chore: Update CODEOWNERS (#10759)
* chore: Update CODEOWNERS

* Update CODEOWNERS

* sort

---------

Co-authored-by: Almeida <github@almeidx.dev>
2025-02-15 13:49:03 +00:00
Luna
b7fd2d105f refactor(Client)!: Remove emojis getter (#10754)
BREAKING CHANGE: Removed `Client#emojis`

---------

Co-authored-by: Danial Raza <danialrazafb@gmail.com>
2025-02-15 13:46:29 +02:00
Amgelo563
4b63bb8046 fix: Do not omit falsy default values (#10755)
* fix(docs): fix default falsy values being omitted

* fix(docs): swap defaultValue check to avoid negated condition

* fix: fix pr by removing everything it added and committing something entirely different

---------

Co-authored-by: almeidx <github@almeidx.dev>
2025-02-12 19:52:02 +00:00
Jiralite
5c49b6d9af docs: Fix close tags (#10756)
* docs: fix close tag

* remove extra spaces

---------

Co-authored-by: Almeida <github@almeidx.dev>
2025-02-12 19:08:07 +00:00
Danial Raza
64494137da types: rename CategoryChannelType to CategoryChannelChildTypes (#10750)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-02-12 11:26:13 +00:00
Almeida
58a111d6fe chore: use Node.js 22 and fix corepack installation (#10746)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-02-11 00:21:09 +00:00
Lobo Metalúrgico
5c48979096 build: Update undici to 6.21.1 (#10743)
fix: undici bumping to 6.21.1

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-02-10 23:07:06 +00:00
Almeida
2183c5eebb fix(EmbedFieldBuilder): allow empty name and value (#10745) 2025-02-10 21:54:31 +00:00
Jiralite
af3ab2211a chore: Update GuildEmojisAndStickers in bug report form (#10741)
chore: update intent name
2025-02-08 15:19:15 +00:00
Jiralite
90105338f0 chore: Remove "typings" scope from cliff.toml (#10738)
chore: remove typings from generator
2025-02-02 15:44:53 +00:00
ŊʂƓ PRIYANSHU
5f463eb9e9 chore: Add contributors and last commit badges (#10428)
* chore: add new fancy badges

* chore: add util

* style: remove extra space

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-29 10:51:05 +00:00
Jiralite
529ce6b472 docs: Use link tags to render links on the documentation (#10731)
* docs: use link tags

* docs(DateResolvable): update link

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-29 09:27:58 +00:00
Jiralite
fa0d4b507d feat: Incident Actions (#10727)
* feat: initial commit

* feat: add guild helper

* docs: `guild` is required

* docs(IncidentActions): move to guild

* fix: `incidents_data` is nullable

* fix: method typo

* fix: default to `null`

* fix: use `new Date()`

* docs: note that it is not received over the gateway

* refactor: use transformer

* chore: resolve TODO

* chore: typo

Co-authored-by: Danial Raza <danialrazafb@gmail.com>

* chore: suggestions

Co-authored-by: Almeida <github@almeidx.dev>

* chore: consistency

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Danial Raza <danialrazafb@gmail.com>
Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-28 19:43:20 +00:00
Danial Raza
6e61ec6358 feat(Client): add request soundboard sounds (#10608)
* feat(Client): add request soundboard sounds

* docs: add `guildId` to example

Co-authored-by: Almeida <github@almeidx.dev>

* refactor: remove `groupBy` polyfill

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-28 12:33:34 +00:00
Jiralite
6df42db33d build: bump discord-api-types to 0.37.118 (#10730) 2025-01-28 10:09:09 +00:00
Jiralite
3db8ce70a2 build!: Bump Node.js to 22.12.0 (#10726)
BREAKING CHANGE: Node.js 22.12.0 or above is required.
2025-01-26 14:56:39 +00:00
Jiralite
9b8b0f828c build: Properly add typecheck tests (#10722)
* build: exclude type tests from running

* refactor: use `tsc`

* test: fix broker test

* test: fix voice test

* test: fix builders test

* test: use vitest typecheck

remove unused test scripts
skip lib check
rm vitest.d.ts

* fix: remove tsd from core and ws

* fix: extend local tsconfig

---------

Co-authored-by: almeidx <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-26 14:28:45 +00:00
cobalt
b820daadd4 fix(GuildAuditLogEntry)!: Fix some incorrect types and runtime logic (#10591)
BREAKING CHANGE: It also doesn't have a `options.channel_id`, so I stopped `.extra.channel` from being set to `{ id: undefined }`
BREAKING CHANGE: Fixed both types and runtime logic here, it previously created a broken `AutoModerationRule`
BREAKING CHANGE: Removed `Targets.GuildOnboarding`, it will fallback to `Targets.Unknown` and generate a placeholder `target` from the `changes`

---------

Signed-off-by: cobalt <61329810+cobaltt7@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>
Co-authored-by: Almeida <github@almeidx.dev>
2025-01-26 13:48:57 +00:00
René
b7e0fe3689 feat(collection): honour subclassing via @@species in static methods (#10723)
* feat(collection): use @@species in static methods

* test(collection): subclassing tests

* chore: trigger ci

---------

Co-authored-by: almeidx <github@almeidx.dev>
2025-01-26 13:14:48 +00:00
Vlad Frangu
0ab6abbcff types: remove fields that cannot be set by the client (#10711)
* types: remove fields that cannot be set by the client

* chore: cleanup JS lands too

* chore: requested changes

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-26 10:34:34 +00:00
Danial Raza
695f592361 refactor!: consolidate parameters into a single options object (#10718)
BREAKING CHANGE: `ApplicationCommandManager#fetch` and `GuildApplicationCommandManager#fetch` no longer accept 2 parameters. Instead, the first parameter accepts `id` or `options` which can now also have the `id` property.

---------

Co-authored-by: Micah Benac <OfficialSirH@users.noreply.github.com>
Co-authored-by: Almeida <github@almeidx.dev>
2025-01-25 20:43:20 +00:00
Almeida
2cbf418008 types!: remove GuildMemberResolvable (#10713)
BREAKING CHANGE: The `GuildMemberResolvable` union has been removed. Use `UserResolvable` instead.
2025-01-24 12:39:37 +00:00
Almeida
670667d65b feat: add auth option in api methods (#10717)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-24 11:23:17 +00:00
Amgelo563
54d8750a2d docs(Message): improve message snapshots description (#10709)
* docs(Message): improve message snapshots description

* docs(Message): remove snapshots single entry callout

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-24 10:32:56 +00:00
Almeida
8e3ab32942 refactor!: return void on bans/kick/addRole/removeRole methods (#10714)
BREAKING CHANGE: The following methods don't return anything: `GuildMember#ban`, `GuildMember#kick`, `GuildMemberManager#ban`, `GuildMemberManager#unban`, `GuildMemberManager#kick`, `GuildMemberManager#addRole`, `GuildMemberManager#removeRole`, `GuildBanManager#create`, and `GuildBanManager#remove`.
2025-01-24 10:21:40 +00:00
Almeida
bbec50b134 style: require file extensions in file imports (#10724) 2025-01-24 10:17:02 +00:00
Almeida
db3cb48246 refactor: use throw instead of Promise.reject (#10712)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Renegade334 <Renegade334@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-24 09:39:05 +00:00
Jiralite
702a3762d1 test: Fix collector tests (#10725)
test: fix collector tests
2025-01-24 09:34:30 +00:00
Naiyar
a3fa1a8dcd feat(interactions): add launchActivity method (#10646)
* feat(interactions): add launchActivity method

* chore: suggestion

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

* chore: suggestion

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

* fix: overload and add tests

* chore: wording

* chore: wording

* chore: spacing

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-24 09:11:18 +00:00
Jiralite
3d85d96f08 docs(guild): Remove "all" for listing guild members (#10719)
docs(guild): remove "all" for listing

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-24 09:03:43 +00:00
Almeida
687e2ae672 refactor!: use AsyncEventEmitter instead of EventEmitter (#10710)
BREAKING CHANGE: The `BaseClient`, `Shard`, `ShardingManager`, and `Collector` classes now extend `AsyncEventEmitter` instead of `EventEmitter`.
2025-01-23 09:20:05 +00:00
Naiyar
aa90f00d11 types(interactions): fix overloads (#10702)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-18 19:19:41 +00:00
Danial Raza
ad6b006d35 refactor: standardize export style to named exports (#10630)
* refactor: standardize export style to named exports

* refactor: export enums directly

* fix: update importing in generateRequires script

* fix: missed places

* feat: add eslint rule

* fix: ci errors

* fix: leftovers

* fix: remove accidentally readded interaction response

* fix: remove interaction response export

* fix: correct collection export

* chore: add another eslint rule

---------

Co-authored-by: almeidx <github@almeidx.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-18 18:58:28 +00:00
Danial Raza
c6e16c3675 types(ThreadOnlyChannel): remove incorrect messages property (#10708)
* types(ThreadOnlyChannel): remove incorrect `messages` property

Co-authored-by: TÆMBØ <TAEMBO@users.noreply.github.com>

* test: t e s t s

* test: revamp tests

---------

Co-authored-by: TÆMBØ <TAEMBO@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-18 07:38:00 +00:00
Vlad Frangu
052ed7fbe7 chore: backport-candidate GitHub label (#10623)
* chore: backport-candidate GitHub label

* chore: sort label script

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-18 07:22:50 +00:00
Danial Raza
21096884b1 types: add undefined to flags for exactOptionalPropertyTypes (#10707) 2025-01-16 19:34:10 +00:00
Idris
0c40bc195e refactor(Emoji)!: make imageURL() change extension dynamically (#10613)
BREAKING CHANGE: Image URLs of emojis now automatically return GIF or static extensions.
BREAKING CHANGE: `CDN#emoji()` now has an `animated` required parameter.
2025-01-16 09:59:28 +00:00
Jiralite
e2bbfe7b13 refactor!: Return only snowflakes for bulk delete (#10704)
BREAKING CHANGE: Bulk deleting will only return the message ids that were deleted.

---------

Co-authored-by: Almeida <github@almeidx.dev>
2025-01-16 09:47:15 +00:00
Danial Raza
6a42c5f929 fix!: move crosspost() to GuildMessageManager (#10703)
BREAKING CHANGE: The `crosspost()` method from `MessageManager` has been moved to `GuildMessageManager`.
2025-01-15 11:29:35 +00:00
Naiyar
1fd587c935 types: Allow only ephemeral for defer reply (#10696)
* fix(types): remove unusable flags from InteractionDeferReplyOptions

* fix: include flags in WebhookMessageEditOptions

* chore: update jsdoc

* fix: wrong order

* chore: specify the flag

* chore: extend MessageEditOptions

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-14 14:16:33 +00:00
Naiyar
a65c982ddb feat(PartialGroupDMChannel): add missing properties (#10502)
* fix(PartialGroupDMChannel): add missing ownerId property

* refactor: make ownerID nullable

* feat: add last_message_id & last_pin_timestamp prop

* feat: add component collector methods

* fix: handle null case

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-14 09:22:14 +00:00
Almeida
18ab0cf62a refactor(actions): removed unnecessary actions (#10666)
Removed actions that were only being used in their
respective websocket handlers. The remaining
actions either were either being used elsewhere or
were using methods from the `GenericAction` class.

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
2025-01-13 11:29:57 +00:00
Almeida
28afb0ca0a refactor: remove data resolver exports (#10701)
refactor!: remove data resolver exports

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:26:31 +00:00
Vlad Frangu
5f7d335290 feat: fetch gateway information without requiring rest in ws (#10651)
* feat: overridable initial gateway URL

* chore: discussion changes

* chore: requested change

* chore: other changes

* Update packages/ws/src/ws/WebSocketManager.ts

* style: run ESLint

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:23:41 +00:00
Digital
1e29bb4049 fix(PresenceUpdate): correctly add user regardless of their properties (#10672)
* fix(PresenceUpdate): correctly add user regardless of their properties

* refactor(PresenceUpdate): reflect partials

* refactor(PresenceUpdate): prettier

* refactor(PresenceUpdate): add import

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:20:44 +00:00
Naiyar
34b6a82935 refactor(IntegrationApplication): move common properties to Application (#10627)
* refactor(IntegrationApplication): move common properties to Application

* fix: remove prop from ClientApplication
2025-01-13 10:16:14 +00:00
Almeida
6314d96ed1 types: remove createComponent and createComponentBuilder (#10687)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-13 10:08:26 +00:00
ckohen
ae0265eefc feat(rest)!: allow passing tokens per request (#10682)
BREAKING CHANGE: `RequestData.authPrefix` has been removed in favor of `RequestData.auth.prefix`
2025-01-13 05:36:05 +00:00
Jiralite
11438c230b refactor!: Unpin @discordjs/collection (#10665)
BREAKING CHANGE: discord.js now uses @discordjs/collection v3—a major version increase.
2025-01-13 04:48:30 +00:00
Naiyar
101bef1c52 fix(InteractionResponses): mark replied true for followUps (#10688)
fix: mark replied true for followUps

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-12 21:52:45 +00:00
Jiralite
7e81d3b6c8 refactor!: Remove InteractionResponse (#10689)
BREAKING CHANGE: `InteractionResponse` has been removed. Create interaction collectors via `with_response` or fetching the reply.
2025-01-12 21:48:08 +00:00
Ryan Munro
f70ab41d56 fix(IntegrationApplication)!: remove hook (#10699)
BREAKING CHANGE: IntegrationApplication#hook has been removed.
2025-01-12 20:51:58 +00:00
Vlad Frangu
24f395412c types: fix recurrence rule types (#10693)
* types: fix recurrence rule types

* fix: endAt not endsAt

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-12 20:22:09 +00:00
Jiralite
3ddb73287b refactor!: Better application command mention format approach (#10639)
BREAKING CHANGE: The parameters of `chatInputApplicationCommandMention()` have been reordered.
2025-01-12 20:09:03 +00:00
Jiralite
91f59cf183 fix(fetchVersions): Sort package versions (#10695)
* fix(fetchVersions): sort package versions

* fix(middleware): fix stable redirect
2025-01-12 19:09:46 +01:00
ckohen
01e64b4e9a fix(actions): respect ratelimits on split docs upload (#10697)
* fix(actions): respect ratelimits on split docs upload

* fix: set failed on missing uploads
2025-01-12 19:05:35 +01:00
Jiralite
9a400730f5 test: Include type checks on builders (#10692)
test: include type checks on builders
2025-01-05 12:16:25 +00:00
GodderE2D
28126cd375 fix: make version and package select openable on mobile (#10684) 2025-01-05 09:59:15 +00:00
Jiralite
0c9901e5e4 style: Run Prettier (#10691)
style: prettier
2025-01-05 02:53:44 +01:00
Jiralite
071015caef test: Add with_response overload tests (#10685)
test: add overload tests

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-05 00:22:58 +00:00
Synbulat Biishev
f5d2926c5a feat(NewsChannel)!: return followed channel data (#8566)
BREAKING CHANGE: `GuildChannelManager#addFollower` and `AnnouncementChannel#addFollower` now return `FollowedChannelData`
2025-01-04 17:43:22 +00:00
Jiralite
1986c2d2a8 fix(Message): Ensure channel is defined for clean content (#10681)
fix(Message): ensure channel is defined for clean content

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-04 17:19:56 +00:00
Jiralite
28a2503845 fix(interactions): options should be optional (#10683)
fix(interactions): fix optional overloads
2025-01-03 23:10:09 +00:00
René
bacc08b45f refactor(PermissionOverwrites)!: cache-independent resolve (#10528)
BREAKING CHANGE: `PermissionOverwrites#resolve`'s `overwrite` arg now requires `type` if the `id` is a Snowflake
2025-01-03 11:40:59 +02:00
Jiralite
9fea0698af fix: Correct guild member banner URL (#10677)
fix: correct guild member banner URL

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2025-01-02 08:19:33 +00:00
ckohen
65883f344e chore(cliff): don't skip breaking commits (#10675)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2025-01-02 00:48:21 +00:00
Almeida
ad0d9a295e chore(create-discord-bot): release create-discord-bot@1.0.0 (#10674)
* chore: fix cliff-jumper config

* chore(create-discord-bot): release create-discord-bot@1.0.0

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
2025-01-01 23:28:01 +00:00
Jiralite
a111cddcea feat: Upgrade create-discord-bot dependencies (#10673)
feat: upgrade cdb deps
2025-01-01 23:13:06 +00:00
pat
bc3a0c8389 fix(voice): mark stream as ended (#10455)
* fix: mark stream as ended

refactor: prefer destroying the stream

* refactor: callback for nextTick

test: wait duration ms to check end

chore: eslint

test: end before timeout

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-31 20:45:24 +00:00
Almeida
a6685a319e build: bump dependencies (#10671) 2024-12-31 21:31:34 +01:00
Denis-Adrian Cristea
b854c7b979 fix(SimpleIdentifyThrottler): don't sleep negative amounts (#10669)
* fix(SimpleIdentifyThrottler): don't sleep negative amounts

* fix: test
2024-12-31 18:16:57 +00:00
Qjuh
b81ad113a0 ci: make docs run succeed for old tags (#10668) 2024-12-30 15:27:43 +01:00
Danial Raza
c484e3de25 feat(Subscription): add renewalSkuIds (#10662) 2024-12-21 22:19:36 +00:00
Danial Raza
f1bce54a28 fix(InteractionResponses): properly resolve message flags (#10660) 2024-12-18 14:39:04 +00:00
Jiralite
35ebcc7d5a refactor!: Remove deprecations (#10645)
BREAKING CHANGE: `GuildsAPI#editUserVoiceState()` has been removed. Use `VoiceAPI#editUserVoiceState()` instead.
BREAKING CHANGE: `GuildsAPI#setUserVoiceState()` has been removed. Use `VoiceAPI#setUserVoiceState()` instead.
BREAKING CHANGE: `InteractionsAPI#sendPremiumRequired()` has been removed.
BREAKING CHANGE: `StickersAPI#getNitroStickers()` has been removed. Use `StickersAPI#getStickers()` instead.
2024-12-13 18:21:10 +00:00
Jiralite
0848fc6b4e fix: Handle unknown versions (#10657) 2024-12-12 20:09:05 +01:00
Danial Raza
fd1958bd67 refactor!: replace isAnySelectMenu with isSelectMenu (#10656)
BREAKING CHANGE: `BaseInteraction#isAnySelectMenu()` has been removed. Use `BaseInteraction#isSelectMenu()` instead.

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-12-12 10:21:00 +00:00
Naiyar
89940d55e3 fix: use Message#interactionMetadata (#10654) 2024-12-12 02:56:22 +00:00
Denis-Adrian Cristea
2ff47d85cf refactor(IContextFetchingStrategy): explicitly name forwarded properties (#10652) 2024-12-10 06:34:15 +00:00
Jiralite
5d00332b8c refactor!: Remove deprecations (#10647)
refactor: remove deprecations

BREAKING CHANGE: `ApplicationCommand#dmPermission` has been removed. Use `ApplicationCommand#contexts` instead.
BREAKING CHANGE: `ApplicationCommandData#dmPermission` has been removed. Use `ApplicationCommandData#contexts` instead.
BREAKING CHANGE: `ApplicationCommandData#setDMPermission` has been removed.
BREAKING CHANGE: `Message#setcon` has been removed. Use `Message#interactionMetadata` instead.
2024-12-09 13:15:57 +00:00
Rodrigo Leitão
310563ba07 refactor(GuildChannel)!: default setParent's lockPermissions to false (#9016)
BREAKING CHANGE: `GuildChannel#setParent`'s `lockPermissions` now defaults to false
2024-12-09 10:51:39 +02:00
Jiralite
231954d630 types(InteractionReplyOptions): Add withResponse (#10637)
types(InteractionReplyOptions): add `withResponse`

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-09 08:44:14 +00:00
Naiyar
1cfc835e97 fix(interactions): wrong return type and missing implementation of with_response in core (#10644)
* fix(types): wrong return type with with_response

* fix: missing implementation of with_response

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-09 08:40:35 +00:00
Almeida
b3d4259f8a refactor!: remove deprecated CDN method overloads (#10649)
BREAKING CHANGE: Removed user avatar decoration overload from `CDN#avatarDecoration()`
BREAKING CHANGE: Removed non-object options overload from `CDN#emoji()`

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-12-09 06:58:47 +00:00
Jiralite
af4018c25f refactor!: Remove underscore (#10648)
BREAKING CHANGE: Removed the `underscore()` formatter. Use `underline()` instead.
2024-12-09 00:02:34 +00:00
Jiralite
00dceb32ba test: Remove unused test (#10638)
test: remove unused test

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-05 23:19:33 +00:00
Jaw0r3k
0ac140cd9f refactor!: escape expanded markdown by default (#9463)
feat: support markdown

BREAKING CHANGE: `heading`, `bulletedList`, `numberedList`, `maskedLink` in `EscapeMarkdownOptions` now defaults to `true`.

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-12-05 22:43:40 +00:00
Jiralite
25633a024e docs(InteractionDeferReplyOptions): Associate flags with its <info> (#10635)
docs(InteractionDeferReplyOptions): move `flags` down
2024-12-05 21:58:47 +00:00
Jaw0r3k
dd430c090d refactor(guild)!: remove deprecated get guild overload (#10052)
BREAKING CHANGE: Removed `GuildsAPI#get` overload that allowed passing options as 2nd parameter

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-12-05 21:05:15 +02:00
Naiyar
6304c0177e feat(ClientApplication): add webhook events (#10588)
* feat(ClientApplication): add webhook events

* refactor: update enum names and add external types

* docs(APITypes): reorder

* chore: requested changes

* chore: requested changes

* docs: remove redundancy

* Update ClientApplication.js

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Almeida <github@almeidx.dev>
2024-12-05 18:52:02 +00:00
Qjuh
07eb3865c4 types: fix Client#lastPingTimestamps (#10634)
* types: fix Client#lastPingTimestamps

* docs: consistency

* types: use ReadonlyCollection
2024-12-05 16:46:38 +00:00
Jiralite
0560842a21 feat(EntitlementManager): Support get entitlement (#10606)
* feat: support get entitlement

* docs: add return type

Co-authored-by: Danial Raza <danialrazafb@gmail.com>

* fix: property typo

Co-authored-by: Almeida <github@almeidx.dev>

* fix: property typo

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Danial Raza <danialrazafb@gmail.com>
Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-05 15:55:50 +00:00
Jiralite
a6390716fe feat(monetization): Add get entitlement endpoint (#10605)
feat(monetization): add get entitlement endpoint

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-05 15:43:35 +00:00
Jiralite
abf4b6103c types: Export some core-specific types (#10620)
types: export core-specific types

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-05 09:09:43 +00:00
Jiralite
eceaa85ad4 fix(ThreadChannel): Make ownerId always present (#10618)
fix: thread owner id is always present

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-05 08:40:46 +00:00
Danial Raza
d0dc864888 fix: update clientReady event name references (#10632) 2024-12-04 17:42:07 +00:00
Qjuh
bd7a995717 feat(website): include reexported members in docs (#10518)
* feat(website): add re-exported members to docs site

* refactor(scripts): rewrite sourceURL for externals

* feat(website): add external badge

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-12-02 18:28:44 +00:00
René
5f0d28c0fe fix(collection)!: default sort comparison algorithm (#10412)
BREAKING CHANGE: This replaces the previously inaccurate default sort algorithm, which may alter sort results where a user-defined comparison function is not provided.
2024-12-02 08:23:48 +00:00
Jiralite
f5445c8104 fix(RoleManager): Fetching roles is not nullable (#10629)
fix(RoleManager): `fetch()` not nullable

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-29 18:40:12 +00:00
Jiralite
a69600546a docs: Typos (#10628)
chore: typos

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-29 17:39:24 +00:00
Jiralite
8efb72e761 refactor(FetchApplicationCommandOptions): Use Locale over LocaleString (#10625)
refactor(FetchApplicationCommandOptions): prefer `Locale`
2024-11-29 09:57:00 +00:00
Vlad Frangu
5b125eeec9 docs: correct discord-api-types URLs (#10622)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-28 17:50:34 +00:00
Danial Raza
a870bc1bd3 refactor: use cache.get() for snowflakes, resolve() otherwise (#10626)
* refactor: use `cache.get()` for snowflakes, `resolve()` otherwise

* fix: requested changes

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

* chore: remove unnecessary `?? null`

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-28 17:48:04 +00:00
Jiralite
9d62ff57d6 refactor(commands): Use Locale over LocaleString (#10624)
* refactor: use `Locale`

* test: update `LocaleString` tests
2024-11-28 17:33:40 +00:00
Ryan Munro
2b0944a92f feat(InteractionResponses)!: support with_response query parameter (#10499)
BREAKING CHANGE: `InteractionDeferUpdateOptions#fetchReply` was removed, use `InteractionDeferUpdateOptions#withResponse` instead

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-11-28 10:32:05 +02:00
Danial Raza
108943a397 feat: add subscriptions (#10541)
* feat: add subscriptions

* types: fix fetch options types

* fix: correct properties in patch method

* chore: requested changes

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

* fix: correct export syntax

* chore(Entitlement): mark `ends_at` as nullable`

* types(FetchSubscriptionOptions): add missing `cache` option

* Revert "types(FetchSubscriptionOptions): add missing `cache` option"

This reverts commit ba472bdc599e1860754e59fce4806610f06ac682.

* chore(Entitlement): mark `startsTimestamp` as nullable

* fix: requested changes

* docs(SubscriptionManager): correct return type

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-28 08:18:44 +00:00
Jiralite
9010b121f4 fix: query is optional for some endpoints (#10621)
* fix(monetization): `query` is optional

* refactor: more defaults
2024-11-28 08:11:23 +00:00
Jiralite
e89c6b66ac build!: Bump Node.js to 20 (#10616)
BREAKING CHANGE: Node.js 20 or above is required.
2024-11-27 16:37:35 +00:00
Jiralite
3a1b3cc8e1 build: Bump discord-api-types to 0.37.109 (#10619)
build: bump discord-api-types
2024-11-27 15:40:21 +00:00
Jiralite
97ffa201a2 test: Update deprecated emoji test (#10607)
test: update deprecated emoji test

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-27 08:31:11 +00:00
Vlad Frangu
0374079c67 chore(deps): bump discord-api-types (#10611) 2024-11-23 00:07:57 +00:00
Jiralite
98153baf91 build: Update dependencies (#10601)
* build: update dependencies

* build: upgrade pnpm to 9.13.2
2024-11-19 10:30:06 +00:00
Jiralite
b03a9e4043 feat: Emit reaction type on gateway events (#10598)
feat: emit reaction type

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-18 11:58:18 +00:00
Jiralite
2fa7d6246f fix(MessageReaction): Address undefined burst properties (#10597)
* fix(MessageReaction): `undefined` burst properties

* refactor: simpler burst colour check

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-18 11:14:29 +00:00
Ryan Munro
40fbd827fa feat(interactions): support with_response query parameter in core (#10512)
* feat(interactions): support with_response query parameter

* fix: address feedback from comments

* chore: remove extraneous documentation

* fix: return type is now undefined

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-17 22:48:30 +00:00
Jiralite
28d5c84ddc style: Run Prettier (#10604)
style: prettier
2024-11-17 22:31:18 +00:00
Jiralite
c8977f29bd docs: Use info markdown (#10603) 2024-11-17 22:22:26 +00:00
Vlad Frangu
7397dfe49e chore(voice): release @discordjs/voice@0.18.0 (#10602)
* chore(voice): release @discordjs/voice@0.18.0

* chore: aes-256 note in readme
2024-11-17 22:17:45 +00:00
pat
9f8b9b1d66 feat(voice)!: add new encryption methods, remove old methods (#10451)
BREAKING CHANGE: This library no longer supports using `tweetnacl` as an encryption library due to Discord deprecating the algorithms that `tweetnacl` helped us support (read more [here](https://discord.com/developers/docs/change-log#voice-encryption-modes)). Please migrate to one of: `sodium-native`, `sodium`, `@stablelib/xchacha20poly1305`, `@noble/ciphers` or `libsodium-wrappers` unless your system supports `aes-256-gcm` (verify by running `require('node:crypto').getCiphers().includes('aes-256-gcm')`).

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
2024-11-18 00:08:51 +02:00
Jiralite
51a017a14e test: Fix builder methods in type test (#10599)
* test: fix builder methods in type test

* test: remove unused import
2024-11-17 12:18:46 +00:00
Qjuh
c45d912c98 refactor(GuildAuditLogsEntry)!: add type guard for narrowing (#10521)
BREAKING CHANGE: removed `GuildAuditLogsEntry.Targets.All` which wasn’t used anywhere

---------

Co-authored-by: Almeida <github@almeidx.dev>
2024-11-15 14:28:06 +00:00
Jiralite
3669d5e112 docs(channel): Clarify emoji parameter (#10595)
* docs(channel): clarify emoji parameter

* docs: actually add `@example`

* docs: clarify the kind of encoding

Co-Authored-By: Vlad Frangu <me@vladfrangu.dev>

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-15 10:04:31 +00:00
Jiralite
6775175459 feat: Voice Channel Effect Send (#10318)
* feat: Voice Channel Send Effects (#9288)

* feat: add soundboard fields

* chore: address TODO

* docs: volume is a closed interval

* types: use `GatewayVoiceChannelEffectSendDispatchData`

* refactor: prefer getting from cache

* fix: correctly access cache

Co-authored-by: Danial Raza <danialrazafb@gmail.com>

---------

Co-authored-by: Danial Raza <danialrazafb@gmail.com>
2024-11-14 21:00:04 +00:00
Jiralite
e2df0e0dbc docs: Remove Node.js 10 notice (#10593)
docs: remove Node.js 10 notice
2024-11-12 06:50:35 +00:00
Naiyar
b8f5a68297 fix(InteractionResponses): throw error on deleting response of unacknowledged interaction (#10587)
fix: error on deleting response of non-acknowledged interaction

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-11 15:48:52 +00:00
cobalt
f2f7f1f65b refactor(formatters): Change :_: emoji name placeholder (#10567)
* Change `:_:` emoji name placeholder

* Update tests

* Format
2024-11-11 00:42:04 +00:00
René
c97310681d types(collection): simplify ambient constructor declaration (#10549)
- deduplicates constructor definition
- removes Collection's "internal" JSDoc description block
- removes unnecessary `extends` clause

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-07 11:12:53 +00:00
René
ea042458a3 perf(collection): optimisations (#10552)
* perf: `merge()`: deduplicate boolean checks

* perf: `toSorted()`: remove redundant closure

* perf: `last[Key]()`: order of operations

- do not perform iterable-to-array until required
- test ! before <

* perf: `{at,keyAt}()`: manually iterate to target

* perf: `first[Key]()`: avoid `Array.from()`

* perf: `map()`: avoid `Array.from()`

* perf: `random[Key]()`: avoid `Array.from()`

* test: `.{at,keyAt}()` indices

* perf: `last[Key]()`: use `.at()`/`.keyAt()` for single element

* perf: `first[Key]()`: use iterable-to-array if returning all

* perf: `random[Key]()`: use `{at,keyAt}()` for single value

- skip iterable-to-array for returning single value
- short-circuit if amount or collection size is zero

* perf: `random[Key]()`: use Durstenfeld shuffle

* refactor: `{key,keyAt}()`: reorder index check

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-07 11:03:26 +00:00
Jiralite
c34a57b798 fix(ThreadChannel): Address parameter type on fetchOwner() (#10579)
* fix(ThreadChannel): address parameter on owner helper method

* docs: fix description

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-05 22:19:48 +00:00
Naiyar
1184b38d3e refactor(ThreadManager)!: match parent ID when fetching a single thread (#10557)
BREAKING CHANGE: `ThreadManager#fetch` now throws when the provided thread ID doesn't belong to the current channel
2024-11-05 13:00:44 +02:00
Danial Raza
939e3644e1 types: add missing Caches managers (#10540)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-05 09:36:41 +00:00
Souji
f02bdc3be3 docs: add note about idempotence to role add/remove routes (#10586)
* chore(docs): Add note about idempotence to role add/remove routes

* chore: remove trailing spaces
2024-11-05 09:29:29 +00:00
Danial Raza
1fd662629d feat: add subscriptions (#10486)
* feat: add subscriptions

* docs: requested changes

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-04 10:48:41 +00:00
Jiralite
ef2a6879d3 feat(GuildMember): Banners (#10384)
* feat: initial support for guild member banners

* feat: serialise in `toJSON()`

* feat: serialise in `toJSON()`

* docs: lowercase i

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-11-04 10:43:34 +00:00
Danial Raza
a9f629b0d3 feat: add soundboard (#10536)
* feat: add soundboard

* chore: disable `jsdoc/check-param-names` rule

* fix: export `SoundboardSoundsAPI`
2024-11-04 10:03:13 +00:00
Pablo
ed78e45706 build: bump discord-api-types version (#10575)
* chore: bump discord-api-types version

* fix: delete extra file
2024-10-27 06:15:28 +00:00
Jiralite
b932b64d94 refactor: remove extra traversing (#10580)
* refactor: remove extra traversion

* refactor(GuildScheduledEventManager): address fetch
2024-10-25 09:39:47 +00:00
Jiralite
48a9c665de refactor(InteractionResponses)!: Remove ephemeral response option (#10564)
BREAKING CHANGE: MessagePayload#isInteraction no longer serves a purpose and has been removed.
BREAKING CHANGE: InteractionDeferReplyOptions no longer accepts ephemeral. Use flags instead.
BREAKING CHANGE: InteractionReplyOptions no longer accepts ephemeral. Use flags instead.
2024-10-22 09:10:30 +03:00
Qjuh
6cbe2487bc fix: missing tsdocConfig in api.json preventing index generation (#10565) 2024-10-19 21:34:51 +02:00
Qjuh
3540c3176c feat(website): type parameters links, builtin doc links, default values (#10515)
* feat(website): links to type parameters, builtin doc links in api.json

* feat(website): show default values for params and props in excerpt

* fix: link in jsdoc

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-10-19 00:04:01 +00:00
Qjuh
93b84ae7a6 refactor!: fix several issues with /ws incorporation (#10556)
BREAKING CHANGE: `Client#ping` is nullable now
2024-10-19 00:53:56 +01:00
Vlad Frangu
a9c92efba1 chore: make semver:major block kodiak (#10548)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-18 23:44:44 +00:00
Qjuh
62fb9de9c9 docs: allow @mixes TSDoc tag for documenting mixins (#10545) 2024-10-16 02:31:04 +02:00
almeidx
960a80dbae docs(Client): fix incorrect managers descriptions
Co-authored-by: Luna <84203950+Wolvinny@users.noreply.github.com>
2024-10-12 01:11:56 +03:00
almeidx
b16d851770 revert: docs: fix incorrect managers descriptions (#10519)
This reverts commit eded459335.
2024-10-12 01:11:56 +03:00
Luna
eded459335 docs(Client): fix incorrect managers descriptions (#10519)
* Edit manager descriptions

Some managers had incorrect descriptions, which applied only to the cache of the manager

* Update Client.js

* remove trailing space
2024-10-11 20:54:55 +00:00
Naiyar
79423c80b4 refactor!: exclude removed events from their enum (#10547)
BREAKING CHANGE: Removed the following members from `Events` enum: `Raw`, `ShardResume`, `ShardError`, `ShardReady`, `ShardReconnecting`, `ShardResume`, `ShardDisconnect`

BREAKING CHANGE: Removed `Reconnecting` from `ShardEvents` enum
2024-10-11 10:44:57 +03:00
Eejit
1925c11a48 fix(GuildScheduledEvent): handle null recurrence_rule (#10543)
* fix(GuildScheduledEvent): handle null recurrence_rule

* refactor: consistency

* feat: implement suggested logic change

* fix: correct data.recurrence_rule check

---------

Co-authored-by: Almeida <github@almeidx.dev>
2024-10-11 04:24:08 +00:00
Denis Cristea
c36728a814 fix(Client): never pass token in ws constructor (#10544)
* fix(Client): never pass token in ws constructor

* chore: don't reassign parameter

Co-authored-by: Almeida <github@almeidx.dev>

---------

Co-authored-by: Almeida <github@almeidx.dev>
2024-10-09 10:49:27 +00:00
Naiyar
c8ef899a68 refactor(NewsChannel)!: rename NewsChannel to AnnouncementChannel (#10532)
BREAKING CHANGE: The `NewsChannel` class was renamed to `AnnouncementChannel`, in line with the type name change
2024-10-09 12:35:12 +03:00
Qjuh
a65c762950 refactor!: fully integrate /ws into mainlib (#10420)
BREAKING CHANGE: `Client#ws` is now a `@discordjs/ws#WebSocketManager`
BREAKING CHANGE: `WebSocketManager` and `WebSocketShard` are now re-exports from `@discordjs/ws`
BREAKING CHANGE: Removed the `WebSocketShardEvents` enum
BREAKING CHANGE: Renamed the `Client#ready` event to `Client#clientReady` event to not confuse it with the gateway `READY` event
BREAKING CHANGE: Added `Client#ping` to replace the old `WebSocketManager#ping`
BREAKING CHANGE: Removed the `Shard#reconnecting` event which wasn’t emitted anymore since 14.8.0 anyway
BREAKING CHANGE: Removed `ShardClientUtil#ids` and `ShardClientUtil#count` in favor of `Client#ws#getShardIds()` and `Client#ws#getShardCount()`
BREAKING CHANGE: `ClientUser#setPresence()` and `ClientPresence#set()` now return a Promise which resolves when the gateway call was sent successfully
BREAKING CHANGE: Removed `Guild#shard` as `WebSocketShard`s are now handled by `@discordjs/ws`
BREAKING CHANGE: Removed the following deprecated `Client` events: `raw`, `shardDisconnect`, `shardError`, `shardReady`, `shardReconnecting`, `shardResume` in favor of events from `@discordjs/ws#WebSocketManager`
BREAKING CHANGE: Removed `ClientOptions#shards` and `ClientOptions#shardCount` in favor of `ClientOptions#ws#shardIds` and `ClientOptions#ws#shardCount`
2024-10-08 22:41:25 +01:00
Denis Cristea
8ab4124ef9 feat: implement zod-validation-error (#10534)
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-06 14:43:06 +00:00
pat
24128a3c45 test: replace jest with vitest (#10472)
* chore: vitest config

* feat: vitest

* fix: do not actually create ws

* chore: config

* chore: lockfile

* chore: revert downgrade, up node

* chore: package - 'git add -A'

* chore: delete mock-socket

* chore: delete mock-socket

* fix: lockfile

---------

Co-authored-by: almeidx <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-06 14:26:53 +00:00
Amgelo563
bb04e09f8b types: remove newMessage partial on messageUpdate event typing (#10526)
* types: remove newMessage partial on messageUpdate event typing

* types: omit partial group DM for newMessage on messageUpdate

* types: omit partial group DM for oldMessage on messageUpdate

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-06 14:23:44 +00:00
Danial Raza
04df3c4130 feat: add linked roles formatters (#10461)
* feat: add linked roles formatters

* docs: requested changes

Co-authored-by: Almeida <github@almeidx.dev>

* docs: remove locale

---------

Co-authored-by: Almeida <github@almeidx.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-06 14:19:50 +00:00
Denis Cristea
12e510671b chore!: remove all deprecated features/props (#10421)
BREAKING CHANGE: Removed `Client#fetchPremiumStickerPacks` method
BREAKING CHANGE: Removed `Client#webhookUpdate` event
BREAKING CHANGE: Removed various error codes
BREAKING CHANGE: Removed `Formatters` namespace
BREAKING CHANGE: Removed `InviteStageInstance` class
BREAKING CHANGE: Removed `Invite#stageInstance` property
BREAKING CHANGE: Removed `StageInstance#discoverable_disabled` property
BREAKING CHANGE: Removed `SelectMenuBuilder` alias
BREAKING CHANGE: Removed `SelectMenuComponent` alias
BREAKING CHANGE: Removed `SelectMenuInteraction` alias
BREAKING CHANGE: Removed `SelectMenuOptionBuilder` alias
BREAKING CHANGE: Removed `BaseInteraction#isSelectMenu` alias
BREAKING CHANGE: Removed `deleteMessageDays` option from `GuildBanManager#create`
BREAKING CHANGE: Removed `ActionRow#from` method
BREAKING CHANGE: Removed `Emoji#url` getter
BREAKING CHANGE: Removed `TeamMember#permissions` property
BREAKING CHANGE: Removed `User#avatarDecoration` property
BREAKING CHANGE: Removed `InteractionResponses#sendPremiumRequired` method
BREAKING CHANGE: Removed `DeletableMessageTypes` constant
2024-10-04 14:17:34 +03:00
Superchupu
c1b849fa5a docs(discord.js): remove utf-8-validate (#10531) 2024-10-03 18:10:46 +00:00
René
b339a7cb08 fix(ThreadMember): remove audit log reason parameter (#10023)
fix(ThreadMember): remove audit log reason

Co-authored-by: René <Renegade334@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-01 16:33:25 +00:00
MrMythicalYT
05541d8288 fix(User): remove fetchFlags() (#8755)
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
2024-10-01 16:29:31 +00:00
Rodrigo Leitão
493a079fdf refactor(CommandInteractionOptionResolver): remove getFull from getFocused() (#9789)
* refactor(CommandInteractionOptionResolver): remove getFull from getFocused()

* docs: update return type

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

---------

Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-01 16:21:42 +00:00
Denis Cristea
ab32f26cbb refactor: builders (#10448)
BREAKING CHANGE: formatters export removed (prev. deprecated)
BREAKING CHANGE: `SelectMenuBuilder` and `SelectMenuOptionBuilder` have been removed (prev. deprecated)
BREAKING CHANGE: `EmbedBuilder` no longer takes camalCase options
BREAKING CHANGE: `ActionRowBuilder` now has specialized `[add/set]X` methods as opposed to the current `[add/set]Components`
BREAKING CHANGE: Removed `equals` methods
BREAKING CHANGE: Sapphire -> zod for validation
BREAKING CHANGE: Removed the ability to pass `null`/`undefined` to clear fields, use `clearX()` instead
BREAKING CHANGE: Renamed all "slash command" symbols to instead use "chat input command"
BREAKING CHANGE: Removed `ContextMenuCommandBuilder` in favor of `MessageCommandBuilder` and `UserCommandBuilder`
BREAKING CHANGE: Removed support for passing the "string key"s of enums
BREAKING CHANGE: Removed `Button` class in favor for specialized classes depending on the style
BREAKING CHANGE: Removed nested `addX` styled-methods in favor of plural `addXs`

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: Almeida <github@almeidx.dev>
2024-10-01 19:11:56 +03:00
Moebits
c633d5c7f6 feat: Add ApplicationEmoji to EmojiResolvable and MessageReaction#emoji (#10477)
* types: add ApplicationEmoji to EmojiResolvable

* typings: add ApplicationEmoji to MessageReaction#emoji

* removed ApplicationEmoji from MessageReaction

* update BaseGuildEmojiManager

* chore: lint error

* feat: add ApplicationEmoji to MessageReaction#emoji getter

* refactor: check application emojis first

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-10-01 12:33:40 +00:00
Qjuh
b20346f430 chore: unpin discord-api-types (#10524)
* chore: unpin discord-api-types

* chore: bump discord-api-types
2024-10-01 10:07:58 +00:00
Almeida
9aa3b635ef feat: recurring scheduled events (#10447)
* feat: recurring scheduled events

* fix: nullable on patch

* docs: remove unnecessary parenthesis

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

---------

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2024-09-29 18:41:57 +00:00
TÆMBØ
e1012cc54a feat: message forwarding (#10464)
* feat: message forwarding

* fix: redundant usage

* feat: add additional snapshot fields

* refactor: use collection to store snapshots

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2024-09-29 11:35:40 +00:00
1013 changed files with 44659 additions and 37110 deletions

3
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,3 @@
# .git-blame-ignore-revs
# switched to eslint-config-neon for mainlib discord.js
b03c65c34c6e8bab7f97d507d6ccd7c441a14360

View File

@@ -2,7 +2,7 @@ version = 1
[merge]
require_automerge_label = false
blocking_labels = ['blocked', 'in review']
blocking_labels = ['blocked', 'in review', 'semver:major']
method = 'squash'
[merge.message]

7
.github/CODEOWNERS vendored
View File

@@ -1,13 +1,18 @@
# Learn how to add code owners here:
# https://help.github.com/en/articles/about-code-owners
# https://help.github.com/articles/about-code-owners
* @iCrawl
package.json @discordjs/core
pnpm-lock.yaml @discordjs/core
/apps/guide/ @discordjs/website @discordjs/guide
/apps/guide/src/content/ @discordjs/guide
/apps/website/ @discordjs/website
/packages/actions/ @discordjs/actions
/packages/api-extractor/ @discordjs/api-extractor-utils
/packages/api-extractor-model/ @discordjs/api-extractor-utils
/packages/api-extractor-utils/ @discordjs/api-extractor-utils
/packages/brokers/ @discordjs/brokers
/packages/builders/ @discordjs/builders

View File

@@ -62,7 +62,7 @@ body:
description: List necessary versions here. This includes your package version, runtime version, operating system etc.
placeholder: |
- discord.js 14.12.1 (`npm ls discord.js` or another package)
- Node.js 16.11.0 (`node --version`)
- Node.js 22.12.0 (`node --version`)
- TypeScript 5.1.6 (`npm ls typescript` if you use it)
- macOS Ventura 13.3.1
validations:
@@ -107,7 +107,7 @@ body:
- Guilds
- GuildMembers
- GuildModeration
- GuildEmojisAndStickers
- GuildExpressions
- GuildIntegrations
- GuildWebhooks
- GuildInvites

4
.github/labels.yml vendored
View File

@@ -10,6 +10,8 @@
color: 7ef7ef
- name: backport
color: 88aabb
- name: backport-candidate
color: 0075ca
- name: blocked
color: fc1423
- name: bug
@@ -38,8 +40,6 @@
color: 80c042
- name: good first issue
color: 7057ff
- name: has PR
color: 4b1f8e
- name: help wanted
color: '008672'
- name: in progress

View File

@@ -1,4 +1,4 @@
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
# https://docs.github.com/actions/using-workflows/caching-dependencies-to-speed-up-workflows#force-deleting-cache-entries
name: Cleanup caches
on:
pull_request:

View File

@@ -16,10 +16,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

View File

@@ -36,10 +36,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

View File

@@ -40,10 +40,10 @@ jobs:
with:
ref: ${{ inputs.ref || '' }}
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache
@@ -60,8 +60,11 @@ jobs:
- name: Build main
if: ${{ inputs.ref && inputs.ref != 'main' }}
shell: bash
env:
COREPACK_ENABLE_STRICT: 0
run: |
cd main
pnpm self-update 10
pnpm install --frozen-lockfile --prefer-offline --loglevel error
pnpm run build
cd ..
@@ -102,8 +105,14 @@ jobs:
- name: Upload documentation to database
if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
uses: ./packages/actions/src/uploadDocumentation
with:
package: ${{ steps.extract-tag.outputs.package }}
@@ -112,8 +121,14 @@ jobs:
- name: Upload documentation to database
if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
uses: ./main/packages/actions/src/uploadDocumentation
with:
package: ${{ steps.extract-tag.outputs.package }}
@@ -122,7 +137,10 @@ jobs:
- name: Upload split documentation to blob storage
if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
env:
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
uses: ./packages/actions/src/uploadSplitDocumentation
with:
package: ${{ steps.extract-tag.outputs.package }}
@@ -131,7 +149,10 @@ jobs:
- name: Upload split documentation to blob storage
if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
env:
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
uses: ./main/packages/actions/src/uploadSplitDocumentation
with:
package: ${{ steps.extract-tag.outputs.package }}
@@ -154,27 +175,45 @@ jobs:
- name: Upload documentation to database
if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
uses: ./packages/actions/src/uploadDocumentation
- name: Upload documentation to database
if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
uses: ./main/packages/actions/src/uploadDocumentation
- name: Upload split documentation to blob storage
if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
env:
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
uses: ./packages/actions/src/uploadSplitDocumentation
- name: Upload split documentation to blob storage
if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
env:
BLOB_READ_WRITE_TOKEN: ${{ secrets.BLOB_READ_WRITE_TOKEN }}
CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
uses: ./main/packages/actions/src/uploadSplitDocumentation
- name: Move docs to correct directory
@@ -213,10 +252,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

View File

@@ -12,10 +12,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

View File

@@ -47,10 +47,10 @@ jobs:
with:
fetch-depth: 0
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
registry-url: https://registry.npmjs.org/
- name: Check the current development version

View File

@@ -9,10 +9,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

View File

@@ -16,10 +16,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
registry-url: https://registry.npmjs.org/
- name: Install dependencies
@@ -39,3 +39,11 @@ jobs:
pnpm --filter=${{ steps.extract-tag.outputs.subpackage == 'true' && '@discordjs/' || '' }}${{ steps.extract-tag.outputs.package }} publish --provenance --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
- name: create-discord-bot -> create-discord-app
if: steps.extract-tag.outputs.package == 'create-discord-bot'
run: |
pnpm --filter=create-discord-bot run rename-to-app
pnpm --filter=create-discord-app publish --provenance --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}

View File

@@ -19,10 +19,10 @@ jobs:
with:
fetch-depth: 0
- name: Install Node.js v20
- name: Install Node.js v22
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- name: Install dependencies
uses: ./packages/actions/src/pnpmCache

1
.gitignore vendored
View File

@@ -17,6 +17,7 @@ pids
# Dist
dist
dist-docs
packages/discord-api-types
# Miscellaneous
.tmp

6
.npmrc
View File

@@ -1,6 +0,0 @@
auto-install-peers=false
resolution-mode=highest
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
public-hoist-pattern[]=*@rushstack/node-core-library*
public-hoist-pattern[]=*jju*

48
.vscode/settings.json vendored
View File

@@ -1,32 +1,54 @@
{
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"eslint.experimental.useFlatConfig": true,
"eslint.workingDirectories": [
{ "directory": "${workspaceFolder}" },
{ "pattern": "./apps/*/" },
{ "pattern": "./packages/*/" }
],
"eslint.useESLintClass": true,
"eslint.useFlatConfig": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": "never",
"source.fixAll.eslint": "explicit",
"source.fixAll": "explicit"
"source.fixAll.eslint": "always",
"source.fixAll": "always"
},
"editor.trimAutoWhitespace": false,
"files.associations": {
"api-extractor.json": "jsonc",
"api-extractor-docs.json": "jsonc",
"tsconfig.json": "jsonc",
"tsconfig.eslint.json": "jsonc",
"tsconfig.docs.json": "jsonc"
"tsconfig.eslint.json": "jsonc"
},
"files.insertFinalNewline": true,
"files.eol": "\n",
"search.exclude": {
"**/.yarn": true,
"**/.next": true,
"**/dist": true,
"**/coverage": true,
"**/test-results": true
},
"search.followSymlinks": false,
"search.useParentIgnoreFiles": true,
"files.watcherExclude": {
"**/.next/*/**": true,
"**/.yarn/*/**": true,
"**/coverage/*/**": true,
"**/dist/*/**": true,
"**/test-results/*/**": true
},
"unocss.disable": true,
"npm.packageManager": "pnpm",
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"unocss.disable": true,
"tailwindCSS.experimental.classRegex": [
["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"],
["cx\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
["class:\\s*?[\"'`]([^\"'`]*).*?,"]
],
"workbench.editor.customLabels.patterns": {
"**/app/**/page.tsx": "${dirname} (${filename}.${extname}) - Page",
"**/app/**/layout.tsx": "${dirname} (${filename}.${extname}) - Layout",
"**/app/**/template.tsx": "${dirname} (${filename}.${extname}) - Template",
"**/app/**/error.tsx": "${dirname} (${filename}.${extname}) - Error",
"**/app/**/not-found.tsx": "${dirname} (${filename}.${extname}) - Not Found",
"**/components/**/page.tsx": "${dirname} (${filename}.${extname}) - Component"
},
"deno.enable": false,
"deno.enablePaths": ["./packages/create-discord-bot/template/Deno"],
"deno.lint": false,

View File

@@ -9,7 +9,9 @@
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="npm version" /></a>
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="npm downloads" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
<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>
<a href="https://github.com/discordjs/discord.js/commits/main"><img src="https://img.shields.io/github/last-commit/discordjs/discord.js.svg?logo=github&logoColor=ffffff" alt="Last commit." /></a>
<a href="https://github.com/discordjs/discord.js/graphs/contributors"><img src="https://img.shields.io/github/contributors/discordjs/discord.js.svg?maxAge=3600&logo=github&logoColor=fff&color=00c7be" alt="contributors" /></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>

View File

@@ -1 +1 @@
METADATA_BASE_URL=http://localhost:3000
NEXT_PUBLIC_LOCAL_DEV=true

View File

@@ -16,13 +16,10 @@ pids
.env*.local
# Dist
.contentlayer
.next
public/searchIndex
src/styles/unocss.css
.source
# Miscellaneous
.tmp
.vscode
lighthouse-results
.vercel

View File

@@ -1,7 +1,8 @@
.contentlayer
.next
.turbo
.vscode
coverage
src/assets/readme
src/styles/unocss.css
next-env.d.ts
.source

View File

@@ -0,0 +1,6 @@
/** @type {import('prettier').Config} */
module.exports = {
...require('../../.prettierrc.json'),
plugins: ['prettier-plugin-tailwindcss'],
tailwindFunctions: ['cva', 'cx'],
};

View File

@@ -1,2 +0,0 @@
/** @type {import('prettier').Config} */
module.exports = require('../../.prettierrc.json');

190
apps/guide/LICENSE Normal file
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.

View File

@@ -14,10 +14,6 @@
</p>
</div>
## About
The official guide for discord.js, made to help you get started easily with the library.
## Links
- [Website][website] ([source][website-source])
@@ -47,6 +43,6 @@ If you don't understand something in the documentation, you are experiencing pro
[guide-update]: https://discordjs.guide/additional-info/changes-in-v14.html
[discord]: https://discord.gg/djs
[discord-api]: https://discord.gg/discord-api
[source]: https://github.com/discordjs/discord.js/tree/main/apps/guide
[source]: https://github.com/discordjs/discord.js/tree/main/apps/website
[related-libs]: https://discord.com/developers/docs/topics/community-resources#libraries
[contributing]: https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md

View File

@@ -0,0 +1,7 @@
---
title: Hello World
---
## Introduction
I love Anime.

View File

@@ -1,94 +0,0 @@
import { remarkCodeHike } from '@code-hike/mdx';
import { defineDocumentType, makeSource } from 'contentlayer/source-files';
import { type Node, toString } from 'hast-util-to-string';
import { h } from 'hastscript';
import { escape } from 'html-escaper';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeSlug from 'rehype-slug';
import remarkGfm from 'remark-gfm';
import codeHikeThemeDarkPlus from './src/styles/code-hike-theme-dark-plus.json';
export const Content = defineDocumentType(() => ({
name: 'Content',
filePathPattern: `**/*.mdx`,
contentType: 'mdx',
fields: {
title: {
type: 'string',
required: true,
},
category: {
type: 'string',
required: true,
},
},
computedFields: {
slug: {
type: 'string',
// eslint-disable-next-line unicorn/prefer-string-replace-all
resolve: (doc) => doc._raw.flattenedPath.replace(/\d+-/g, ''),
},
url: {
type: 'string',
// eslint-disable-next-line unicorn/prefer-string-replace-all
resolve: (doc) => `/guide/${doc._raw.flattenedPath.replace(/\d+-/g, '')}`,
},
},
}));
const LinkIcon = h(
'svg',
{
width: '1.25rem',
height: '1.25rem',
viewBox: '0 0 24 24',
fill: 'none',
stroke: 'currentColor',
strokeWidth: '2',
strokeLinecap: 'round',
strokeLinejoin: 'round',
},
h('path', {
// eslint-disable-next-line id-length
d: 'M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71',
}),
h('path', {
// eslint-disable-next-line id-length
d: 'M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71',
}),
);
const createSROnlyLabel = (text: any) => {
return h('span', { class: 'sr-only' }, `Section titled ${escape(text)}`);
};
export default makeSource({
contentDirPath: 'src/content',
documentTypes: [Content],
mdx: {
remarkPlugins: [remarkGfm, [remarkCodeHike, { theme: codeHikeThemeDarkPlus, lineNumbers: true }]],
rehypePlugins: [
rehypeSlug,
[
rehypeAutolinkHeadings,
{
properties: {
class:
'relative inline-flex place-items-center place-content-center outline-none text-black dark:text-white pr-2 -ml-8 opacity-0 group-hover:opacity-100',
},
behavior: 'prepend',
content: (heading: Node) => [
h(
`span.anchor-icon`,
{
ariaHidden: 'true',
},
LinkIcon,
),
createSROnlyLabel(toString(heading)),
],
},
],
],
},
});

View File

@@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -1,17 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable @typescript-eslint/no-require-imports */
// import { withContentlayer } from 'next-contentlayer';
const { withContentlayer } = require('next-contentlayer');
module.exports = withContentlayer({
reactStrictMode: true,
experimental: {
typedRoutes: true,
},
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; frame-src 'none'; sandbox;",
},
poweredByHeader: false,
});

38
apps/guide/next.config.ts Normal file
View File

@@ -0,0 +1,38 @@
import { createMDX } from 'fumadocs-mdx/next';
import type { NextConfig } from 'next';
const withMDX = createMDX();
export default withMDX({
reactStrictMode: true,
serverExternalPackages: ['typescript', 'twoslash'],
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; frame-src 'none'; sandbox;",
remotePatterns: [
{
protocol: 'http',
hostname: 'localhost',
},
],
},
poweredByHeader: false,
logging: {
fetches: {
fullUrl: true,
},
},
experimental: {
ppr: true,
reactCompiler: true,
useCache: true,
dynamicOnHover: true,
},
eslint: {
ignoreDuringBuilds: true,
},
typescript: {
ignoreBuildErrors: true,
},
} satisfies NextConfig);

View File

@@ -2,22 +2,21 @@
"$schema": "https://json.schemastore.org/package.json",
"name": "@discordjs/guide",
"version": "0.1.0",
"description": "Imagine a guide... that explores the many possibilities for your discord.js bot",
"description": "Imagine a bot... the most popular way to build discord bots",
"private": true,
"scripts": {
"test": "vitest run",
"build:check": "tsc --noEmit",
"build:local": "pnpm run build:prod",
"build:prod": "next build",
"build:analyze": "cross-env ANALYZE=true pnpm run build:prod",
"build:local": "cross-env NEXT_PUBLIC_LOCAL_DEV=true pnpm run build:prod",
"build:prod": "pnpm run build:next",
"build:next": "next build",
"preview": "next start",
"dev": "next dev",
"generate:contentlayer": "contentlayer build",
"lint": "pnpm run build:check && prettier --check . && cross-env TIMING=1 eslint --format=pretty src",
"format": "pnpm run build:check && prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src",
"fmt": "pnpm run format"
"dev": "next dev -p 3001 --turbopack",
"lint": "pnpm run build:check && prettier --check . && cross-env TIMING=1 eslint --format=pretty src ",
"format": "pnpm run build:check && prettier --write . && cross-env TIMING=1 eslint --fix --format=pretty src ",
"fmt": "pnpm run format",
"postinstall": "fumadocs-mdx"
},
"type": "commonjs",
"type": "module",
"directories": {
"lib": "src"
},
@@ -37,7 +36,7 @@
"repository": {
"type": "git",
"url": "https://github.com/discordjs/discord.js.git",
"directory": "apps/guide"
"directory": "apps/website"
},
"bugs": {
"url": "https://github.com/discordjs/discord.js/issues"
@@ -45,55 +44,66 @@
"homepage": "https://discord.js.org",
"funding": "https://github.com/discordjs/discord.js?sponsor",
"dependencies": {
"@code-hike/mdx": "^0.9.0",
"@discordjs/ui": "workspace:^",
"@react-icons/all-files": "^4.1.0",
"@vercel/analytics": "^1.3.1",
"@vercel/edge-config": "^1.1.1",
"@vercel/og": "^0.6.2",
"ariakit": "2.0.0-next.44",
"cmdk": "^1.0.0",
"contentlayer": "^0.3.4",
"next": "^14.2.3",
"next-contentlayer": "^0.3.4",
"next-themes": "^0.3.0",
"react": "^18.3.1",
"react-custom-scrollbars-2": "^4.5.0",
"react-dom": "^18.3.1",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.1.0",
"remark-gfm": "^3.0.1",
"sharp": "^0.33.4"
"@vercel/analytics": "^1.5.0",
"cmdk": "^1.1.1",
"cva": "1.0.0-beta.3",
"fumadocs-core": "^15.4.2",
"fumadocs-mdx": "^11.6.6",
"fumadocs-twoslash": "^3.1.3",
"fumadocs-ui": "^15.4.2",
"geist": "^1.4.2",
"immer": "^10.1.1",
"jotai": "^2.12.5",
"jotai-immer": "^0.4.1",
"lucide-react": "^0.511.0",
"motion": "^12.15.0",
"next": "15.4.0-canary.11",
"next-mdx-remote-client": "^2.1.2",
"next-themes": "^0.4.6",
"nuqs": "^2.4.3",
"react": "^19.1.0",
"react-aria": "^3.40.0",
"react-aria-components": "^1.9.0",
"react-dom": "^19.1.0",
"react-error-boundary": "^6.0.0",
"sharp": "^0.34.2",
"tailwind-merge": "^3.3.0",
"tw-animate-css": "^1.3.2",
"twoslash": "^0.3.1",
"usehooks-ts": "^3.1.1"
},
"devDependencies": {
"@testing-library/react": "^15.0.7",
"@testing-library/user-event": "^14.5.2",
"@types/html-escaper": "^3.0.2",
"@types/node": "^18.19.45",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@unocss/eslint-plugin": "^0.60.4",
"@unocss/postcss": "^0.60.4",
"@unocss/reset": "^0.60.4",
"@vitejs/plugin-react": "^4.3.0",
"@vitest/coverage-v8": "^2.0.5",
"@next/env": "^15.3.3",
"@shikijs/rehype": "^3.4.2",
"@tailwindcss/postcss": "^4.1.8",
"@tailwindcss/typography": "^0.5.16",
"@tailwindcss/vite": "^4.1.8",
"@types/mdx": "^2.0.13",
"@types/node": "^22.15.26",
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.5",
"autoprefixer": "^10.4.21",
"babel-plugin-react-compiler": "19.1.0-rc.2",
"cpy-cli": "^5.0.0",
"cross-env": "^7.0.3",
"eslint": "^8.57.0",
"eslint-config-neon": "^0.1.62",
"eslint": "^9.27.0",
"eslint-config-neon": "^0.2.7",
"eslint-formatter-pretty": "^6.0.1",
"happy-dom": "^14.12.0",
"hast-util-to-string": "^2.0.0",
"hastscript": "^8.0.0",
"html-escaper": "^3.0.3",
"postcss": "^8.4.38",
"prettier": "^3.3.3",
"turbo": "^2.0.14",
"typescript": "~5.5.4",
"unocss": "^0.60.4",
"vercel": "^37.0.0",
"vitest": "^2.0.5"
"git-describe": "^4.1.1",
"postcss": "^8.5.4",
"prettier": "^3.5.3",
"prettier-plugin-tailwindcss": "^0.6.11",
"remark-gfm": "^4.0.1",
"remark-rehype": "^11.1.2",
"shiki": "^3.4.2",
"tailwindcss": "^4.1.8",
"tailwindcss-react-aria-components": "^2.0.0",
"turbo": "^2.5.3",
"typescript": "^5.8.2",
"vercel": "^42.2.0"
},
"engines": {
"node": ">=18"
"node": ">=22.12.0"
}
}

View File

@@ -1,5 +0,0 @@
module.exports = {
plugins: {
'@unocss/postcss': {},
},
};

View File

@@ -0,0 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -0,0 +1,35 @@
<svg width="5232" height="945" viewBox="0 0 5232 945" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_dd)">
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="3979" y="20" width="1245" height="907">
<path d="M4685.1 692.37C4747.89 751.167 4832.06 791.257 4913.55 791.257C5011.09 791.257 5065.87 747.156 5065.87 679.006C5065.87 606.85 5009.75 584.134 4929.59 550.728L4810.68 498.614C4723.84 462.533 4634.33 394.383 4634.33 266.097C4634.33 127.126 4757.25 20.2217 4926.92 20.2217C5029.79 20.2217 5128.66 62.9858 5196.8 131.136L5116.63 230.019C5061.85 183.252 5001.74 155.187 4926.92 155.187C4844.08 155.187 4790.64 193.941 4790.64 258.082C4790.64 326.232 4857.45 351.623 4929.59 381.019L5047.17 430.464C5151.37 474.558 5223.51 540.035 5223.51 666.98C5223.51 808.627 5105.94 926.221 4909.56 926.221C4791.98 926.221 4678.42 879.451 4595.59 797.937L4685.1 692.37Z" fill="white"/>
<path d="M4362.62 20.2217H4514.42V625.218C4514.42 785.559 4419.32 925.689 4236.89 925.689C4112.78 933.776 4006.36 848.244 3979.19 761.134C4001.8 757.707 4023.82 754.196 4051.3 745.549C4073.15 738.673 4105.83 723.903 4105.83 723.903C4130.43 763.127 4173.98 789.193 4223.6 789.193C4300.39 789.193 4362.64 726.761 4362.64 649.746L4362.62 20.2217Z" fill="white"/>
</mask>
<g mask="url(#mask0)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3958.82 72.292L4012.02 47.467C4066.83 24.1022 4174.84 -22.6272 4282.85 -34.3096C4390.86 -45.992 4498.87 -22.6272 4606.88 -28.4684C4713.28 -34.3096 4821.29 -69.3567 4929.3 -45.992C5037.31 -22.6272 5145.32 59.1493 5200.14 101.498L5253.33 142.386V247.527H5200.14C5145.32 247.527 5037.31 247.527 4929.3 247.527C4821.29 247.527 4713.28 247.527 4606.88 247.527C4498.87 247.527 4390.86 247.527 4282.85 247.527C4174.84 247.527 4066.83 247.527 4012.02 247.527H3958.82V72.292Z" fill="#FF5C5C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3958.82 76.645L4012.02 115.335C4066.83 154.026 4174.84 233.019 4282.85 233.019C4390.86 233.019 4498.87 154.026 4606.88 128.232C4713.28 102.439 4821.29 128.232 4929.3 141.129C5037.31 154.026 5145.32 154.026 5200.14 154.026H5253.33V426.47H5200.14C5145.32 426.47 5037.31 426.47 4929.3 426.47C4821.29 426.47 4713.28 426.47 4606.88 426.47C4498.87 426.47 4390.86 426.47 4282.85 426.47C4174.84 426.47 4066.83 426.47 4012.02 426.47H3958.82V76.645Z" fill="#F79454"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3958.82 247.527L4012.02 265.951C4066.83 284.375 4174.84 321.223 4282.85 321.223C4390.86 321.223 4498.87 284.375 4606.88 275.163C4713.28 265.951 4821.29 284.375 4929.3 316.617C5037.31 348.859 5145.32 396.071 5200.14 419.101L5253.33 442.131V497.403H5200.14C5145.32 497.403 5037.31 497.403 4929.3 497.403C4821.29 497.403 4713.28 497.403 4606.88 497.403C4498.87 497.403 4390.86 497.403 4282.85 497.403C4174.84 497.403 4066.83 497.403 4012.02 497.403H3958.82V247.527Z" fill="#FFDB5C"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3958.82 407.125L4012.76 420.44C4066.7 433.755 4174.57 460.384 4282.45 460.384C4390.32 460.384 4498.2 433.755 4606.08 440.412C4713.95 447.07 4821.83 487.014 4929.71 487.014C5037.58 487.014 5145.46 447.07 5199.4 427.098L5253.33 407.125V766.624H5199.4C5145.46 766.624 5037.58 766.624 4929.71 766.624C4821.83 766.624 4713.95 766.624 4606.08 766.624C4498.2 766.624 4390.32 766.624 4282.45 766.624C4174.57 766.624 4066.7 766.624 4012.76 766.624H3958.82V407.125Z" fill="#5CFF9D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5253.34 600.577L5200.14 613.169C5145.33 625.76 5037.31 650.943 4929.3 644.648C4821.29 638.352 4713.28 600.577 4605.27 600.577C4498.87 600.577 4390.86 638.352 4282.85 657.239C4174.84 677.7 4066.83 677.7 4012.02 677.7H3958.82V866.573H4012.02C4066.83 866.573 4174.84 866.573 4282.85 866.573C4390.86 866.573 4498.87 866.573 4605.27 866.573C4713.28 866.573 4821.29 866.573 4929.3 866.573C5037.31 866.573 5145.33 866.573 5200.14 866.573H5253.34V600.577Z" fill="#5C6CFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3958.82 760.175L4090.21 692.467C4132.12 760.175 4174.84 794.363 4282.85 798.637C4390.86 802.91 4498.87 772.266 4606.88 772.266C4713.28 772.266 4821.29 802.91 4929.3 798.637C5037.31 794.363 5179.98 760.175 5229.96 740.024L5253.33 760.175V940.73H5200.14C5145.32 940.73 5037.31 940.73 4929.3 940.73C4821.29 940.73 4713.28 940.73 4606.88 940.73C4498.87 940.73 4390.86 940.73 4282.85 940.73C4174.84 940.73 4066.83 940.73 4012.02 940.73H3958.82V760.175Z" fill="#B75CFF"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4264.21 348.906C4264.21 282.978 4251.78 225.648 4226.94 175.965C4201.14 127.234 4163.88 89.0164 4114.19 61.3076C4064.51 33.5989 4004.32 20.2217 3932.65 20.2217H3667.03V689.056H3892.98H3920.23C3986.6 689.056 4037.45 678.548 4084.65 654.747C4084.59 653.088 4084.57 651.421 4084.57 649.746C4084.57 572.732 4146.82 510.3 4223.61 510.3C4225.89 510.3 4228.16 510.355 4230.41 510.464C4254.5 461.424 4264.21 412.805 4264.21 348.906ZM3827.55 163.544V545.734H3918.32C3976.61 545.734 4020.56 528.534 4050.18 493.183C4079.8 458.785 4095.08 411.967 4095.08 351.772C4095.08 292.533 4080.75 246.67 4052.09 213.229C4023.42 179.786 3980.43 163.544 3924.05 163.544H3827.55Z" fill="#5865F2"/>
<path d="M4311.87 649.747C4311.87 698.271 4272.53 737.606 4224.01 737.606C4175.49 737.606 4136.15 698.271 4136.15 649.747C4136.15 601.222 4175.49 561.887 4224.01 561.887C4272.53 561.887 4311.87 601.222 4311.87 649.747Z" fill="#5865F2"/>
<path d="M261.386 689.469C335.011 689.469 398.119 675.125 449.752 645.481C501.386 616.793 540.589 576.63 566.405 524.991C592.222 474.309 605.609 415.02 605.609 349.038C605.609 283.055 593.178 225.679 568.318 175.953C542.501 127.184 505.21 88.933 455.489 61.2012C405.768 33.4694 345.529 20.0816 273.816 20.0816H8V689.469H261.386ZM168.637 546.029V163.522H265.211C321.625 163.522 364.653 179.778 393.338 213.248C422.023 246.717 436.366 292.618 436.366 351.907C436.366 412.152 421.067 459.009 391.426 493.434C361.784 528.816 317.8 546.029 259.474 546.029H168.637ZM878.299 20.0816H717.662V689.469H878.299V20.0816ZM1237.12 709.551C1316.48 709.551 1379.59 690.426 1425.48 651.219C1470.42 612.968 1493.37 560.373 1493.37 494.391C1493.37 444.665 1479.03 403.545 1450.34 371.032C1421.66 339.475 1375.76 312.7 1311.7 292.618L1242.85 270.624C1217.04 260.105 1198.87 249.586 1187.4 239.067C1174.97 228.548 1169.23 216.117 1169.23 199.86C1169.23 159.697 1200.78 139.615 1264.85 139.615C1332.74 139.615 1397.76 161.609 1460.86 206.554V59.2886C1393.93 20.0816 1323.17 0 1247.64 0C1170.19 0 1108.99 18.1691 1065.01 54.5072C1021.02 91.8017 999.031 141.528 999.031 205.598C999.031 253.411 1012.42 292.618 1038.23 323.219C1064.05 354.775 1106.12 379.638 1163.49 399.72L1241.9 425.539C1269.63 437.014 1288.75 447.534 1299.27 458.052C1309.79 468.571 1314.57 482.915 1314.57 499.172C1314.57 545.073 1283.01 568.023 1218.95 568.023C1180.7 568.023 1142.46 560.373 1103.25 546.029C1064.05 531.685 1029.63 513.516 999.031 489.609V638.787C1070.74 685.644 1150.11 709.551 1237.12 709.551ZM1921.29 708.595C1962.43 708.595 2002.57 702.857 2039.85 692.338C2077.17 681.819 2109.67 667.475 2137.39 649.306V502.997C2112.53 520.21 2084.8 533.598 2053.26 544.116C2021.69 554.635 1990.15 560.373 1957.64 560.373C1912.69 560.373 1872.53 551.767 1839.06 533.598C1805.6 516.385 1779.78 492.478 1761.61 460.921C1743.45 429.364 1733.89 393.982 1733.89 353.819C1733.89 313.656 1743.45 278.274 1761.61 246.717C1779.78 215.16 1805.6 191.254 1839.06 174.041C1872.53 156.828 1910.77 148.221 1955.72 148.221C2020.73 148.221 2080.02 168.303 2134.54 207.51V55.4635C2072.39 19.1253 2002.57 0.956277 1923.22 0.956277C1851.49 0.956277 1788.39 16.2564 1734.84 46.857C1680.34 77.4576 1639.22 119.533 1609.58 174.041C1579.94 228.548 1565.6 289.749 1565.6 358.601C1565.6 423.627 1579.94 482.915 1607.67 535.51C1635.4 589.061 1676.51 631.137 1730.06 661.737C1783.61 693.294 1847.67 708.595 1921.29 708.595ZM2561.67 708.595C2629.56 708.595 2689.82 693.294 2743.34 663.65C2795.93 634.006 2838.02 591.93 2867.64 538.379C2897.29 484.828 2911.63 423.627 2911.63 355.732C2911.63 287.837 2897.29 226.635 2867.64 172.128C2838.02 118.577 2795.93 76.5013 2743.34 45.9007C2689.82 16.2564 2629.56 0.956277 2561.67 0.956277C2494.73 0.956277 2434.51 16.2564 2381.92 45.9007C2329.33 76.5013 2288.22 118.577 2258.58 172.128C2228.93 226.635 2213.62 287.837 2213.62 355.732C2213.62 423.627 2228.93 484.828 2258.58 538.379C2288.22 591.93 2329.33 634.006 2381.92 663.65C2434.51 693.294 2494.73 708.595 2561.67 708.595ZM2561.67 556.548C2525.34 556.548 2493.8 547.942 2467.01 530.729C2439.29 513.516 2418.24 489.609 2403.9 459.009C2389.56 429.364 2381.92 394.939 2381.92 356.688C2381.92 318.437 2389.56 284.012 2403.9 252.455C2418.24 221.854 2439.29 197.948 2467.01 179.778C2493.8 161.609 2525.34 153.003 2561.67 153.003C2598.98 153.003 2630.52 161.609 2658.25 179.778C2685.97 197.948 2707.02 221.854 2721.36 252.455C2735.7 284.012 2742.41 318.437 2742.41 356.688C2742.41 394.939 2734.74 429.364 2720.4 459.009C2706.05 489.609 2685.04 513.516 2658.25 530.729C2630.52 547.942 2598.98 556.548 2561.67 556.548ZM3373.13 419.802C3431.46 413.108 3475.42 392.07 3507 357.644C3538.54 323.219 3553.84 279.23 3553.84 226.635C3553.84 162.565 3532.8 112.84 3489.77 75.5452C3446.74 38.2507 3388.44 20.0816 3315.76 20.0816H3021.24V689.469H3181.9V407.37L3379.81 689.469H3572L3373.13 419.802ZM3181.9 154.915H3285.15C3316.72 154.915 3340.63 162.566 3356.87 176.91C3373.13 192.21 3381.73 214.204 3381.73 241.936C3381.73 271.58 3372.17 293.574 3354.01 309.831C3335.85 326.087 3309.06 333.738 3273.7 333.738H3181.9V154.915Z" fill="#5865F2"/>
</g>
<defs>
<filter id="filter0_dd" x="0" y="0" width="5232" height="945" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="10"/>
<feGaussianBlur stdDeviation="4"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.04 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="1.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/>
<feBlend mode="normal" in2="effect1_dropShadow" result="effect2_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow" result="shape"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "discord.js guide",
"short_name": "discord.js guide",
"name": "discord.js",
"short_name": "discord.js",
"icons": [
{
"src": "/android-chrome-192x192.png",

View File

@@ -0,0 +1,24 @@
import { rehypeCodeDefaultOptions } from 'fumadocs-core/mdx-plugins';
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
import { transformerTwoslash } from 'fumadocs-twoslash';
import { createFileSystemTypesCache } from 'fumadocs-twoslash/cache-fs';
export const docs = defineDocs({
dir: 'content/docs',
});
transformerTwoslash({
typesCache: createFileSystemTypesCache(),
});
export default defineConfig({
mdxOptions: {
rehypeCodeOptions: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
transformers: [...(rehypeCodeDefaultOptions.transformers ?? []), transformerTwoslash()],
},
},
});

View File

@@ -1,26 +0,0 @@
'use client';
import { inter } from '~/util/fonts';
import { Providers } from './providers';
import '~/styles/cmdk.css';
import '~/styles/main.css';
export default function GlobalError({ error }: { readonly error: Error }) {
console.error(error);
return (
<html className={inter.variable} lang="en" suppressHydrationWarning>
<body className="bg-light-600 dark:bg-dark-600 dark:text-light-900">
<Providers>
<main className="mx-auto max-w-2xl min-h-screen">
<div className="mx-auto max-w-lg min-h-screen flex flex-col place-content-center place-items-center gap-8 px-8 py-16 lg:px-6 lg:py-0">
<h1 className="text-[9rem] font-black leading-none md:text-[12rem]">500</h1>
<h2 className="text-[2rem] md:text-[3rem]">Error.</h2>
</div>
</main>
</Providers>
</body>
</html>
);
}

View File

@@ -0,0 +1,4 @@
import { createFromSource } from 'fumadocs-core/search/server';
import { source } from '@/lib/source';
export const { GET } = createFromSource(source);

View File

@@ -0,0 +1,36 @@
import { generateOGImage } from 'fumadocs-ui/og';
import { notFound } from 'next/navigation';
import { source } from '@/lib/source';
export function generateStaticParams() {
return source.generateParams().map((page) => ({
...page,
slug: [...page.slug, 'image.png'],
}));
}
export async function GET(_req: Request, { params }: { params: Promise<{ slug: string[] }> }) {
const { slug } = await params;
const page = source.getPage(slug.slice(0, -1));
// const fontData = await fetch(new URL('../../../assets/Geist-Regular.ttf', import.meta.url), {
// next: { revalidate: 604_800 },
// }).then(async (res) => res.arrayBuffer());
if (!page) {
notFound();
}
return generateOGImage({
title: page.data.title,
description: page.data.description,
site: 'discord.js Guide',
// fonts: [
// {
// name: 'Geist',
// data: fontData,
// weight: 900,
// style: 'normal',
// },
// ],
});
}

View File

@@ -1,12 +0,0 @@
'use client';
export default function Error({ error }: { readonly error: Error }) {
console.error(error);
return (
<div className="mx-auto max-w-lg min-h-screen flex flex-col place-content-center place-items-center gap-8 px-8 py-16 lg:px-6 lg:py-0">
<h1 className="text-[9rem] font-black leading-none md:text-[12rem]">500</h1>
<h2 className="text-[2rem] md:text-[3rem]">Error.</h2>
</div>
);
}

View File

@@ -1 +0,0 @@
export { default } from '~/app/not-found';

View File

@@ -1,21 +0,0 @@
import { notFound } from 'next/navigation';
import { allContents } from 'contentlayer/generated';
import { Mdx } from '~/components/Mdx';
export async function generateStaticParams() {
return allContents.map((content) => ({ slug: [content.slug] }));
}
export default function Page({ params }: { readonly params: { slug: string[] } }) {
const content = allContents.find((content) => content.slug === params.slug?.join('/'));
if (!content) {
notFound();
}
return (
<article className="max-w-none px-5 prose">
<Mdx code={content?.body.code ?? ''} />
</article>
);
}

View File

@@ -0,0 +1,53 @@
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { source } from '@/lib/source';
import { getMDXComponents } from '@/mdx-components';
export async function generateStaticParams() {
return source.generateParams();
}
export async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) {
notFound();
}
const image = ['/docs-og', ...(params.slug ?? []), 'image.png'].join('/');
return {
title: page.data.title,
description: page.data.description,
openGraph: {
images: image,
},
twitter: {
card: 'summary_large_image',
images: image,
},
} satisfies Metadata;
}
export default async function Page(props: { readonly params: Promise<{ slug?: string[] }> }) {
const params = await props.params;
const page = source.getPage(params.slug);
if (!page) {
notFound();
}
const MDX = page.data.body;
return (
<DocsPage full={page.data.full!} toc={page.data.toc}>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
{/* eslint-disable-next-line @stylistic/jsx/jsx-pascal-case */}
<MDX components={getMDXComponents()} />
</DocsBody>
</DocsPage>
);
}

View File

@@ -1,25 +1,12 @@
import type { PropsWithChildren } from 'react';
import Footer from '~/components/Footer';
import Header from '~/components/Header';
import { Nav } from '~/components/Nav';
import { Providers } from './providers';
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { source } from '@/lib/source';
export default function Layout({ children }: PropsWithChildren) {
export default function Layout({ children }: { readonly children: ReactNode }) {
return (
<Providers>
<main className="mx-auto max-w-7xl px-4 lg:max-w-full">
<Header />
<div className="relative top-6 mx-auto max-w-7xl gap-6 lg:max-w-full lg:flex">
<div className="lg:sticky lg:top-23 lg:h-[calc(100vh_-_105px)]">
<Nav />
</div>
<div className="mx-auto max-w-5xl min-w-xs w-full pb-10">
{children}
<Footer />
</div>
</div>
</main>
</Providers>
<DocsLayout tree={source.pageTree} {...baseOptions}>
{children}
</DocsLayout>
);
}

View File

@@ -1,3 +0,0 @@
export default function Page() {
return null;
}

View File

@@ -1,8 +0,0 @@
'use client';
import type { PropsWithChildren } from 'react';
import { NavProvider } from '~/contexts/nav';
export function Providers({ children }: PropsWithChildren) {
return <NavProvider>{children}</NavProvider>;
}

View File

@@ -0,0 +1,7 @@
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
export const baseOptions: BaseLayoutProps = {
nav: {
title: 'discord.js Guide',
},
};

View File

@@ -1,29 +1,27 @@
import { Analytics } from '@vercel/analytics/react';
import { RootProvider } from 'fumadocs-ui/provider';
import { GeistMono } from 'geist/font/mono';
import { GeistSans } from 'geist/font/sans';
import type { Metadata, Viewport } from 'next';
import type { PropsWithChildren } from 'react';
import { DESCRIPTION } from '~/util/constants';
import { inter, jetBrainsMono } from '~/util/fonts';
import { Providers } from './providers';
import { ENV } from '@/util/env';
import '~/styles/cmdk.css';
import '@code-hike/mdx/styles.css';
import '~/styles/ch.css';
import '~/styles/main.css';
import '@/styles/base.css';
export const viewport: Viewport = {
themeColor: [
{ media: '(prefers-color-scheme: light)', color: '#f1f3f5' },
{ media: '(prefers-color-scheme: dark)', color: '#181818' },
{ media: '(prefers-color-scheme: light)', color: '#fbfbfb' },
{ media: '(prefers-color-scheme: dark)', color: '#1a1a1e' },
],
colorScheme: 'light dark',
};
export const metadata: Metadata = {
metadataBase: new URL(
process.env.METADATA_BASE_URL ? process.env.METADATA_BASE_URL : `http://localhost:${process.env.PORT ?? 3_000}`,
),
title: 'discord.js',
description: DESCRIPTION,
metadataBase: new URL(ENV.IS_LOCAL_DEV ? `http://localhost:${ENV.PORT}` : 'https://next.discordjs.guide'),
title: {
template: '%s | discord.js',
default: 'discord.js',
},
icons: {
other: [
{
@@ -58,7 +56,6 @@ export const metadata: Metadata = {
siteName: 'discord.js',
type: 'website',
title: 'discord.js',
description: DESCRIPTION,
images: 'https://discordjs.dev/api/open-graph.png',
},
@@ -68,15 +65,15 @@ export const metadata: Metadata = {
},
other: {
'msapplication-TileColor': '#090a16',
'msapplication-TileColor': '#1a1a1e',
},
};
export default function RootLayout({ children }: PropsWithChildren) {
export default async function RootLayout({ children }: PropsWithChildren) {
return (
<html className={`${inter.variable} ${jetBrainsMono.variable}`} lang="en" suppressHydrationWarning>
<body className="bg-light-600 dark:bg-dark-600 dark:text-light-900">
<Providers>{children}</Providers>
<html className={`${GeistSans.variable} ${GeistMono.variable} antialiased`} lang="en" suppressHydrationWarning>
<body className="overscroll-y-none">
<RootProvider>{children}</RootProvider>
<Analytics />
</body>
</html>

View File

@@ -1,20 +0,0 @@
export default function Loading() {
return (
<div className="mx-4 min-h-screen flex flex-col items-center justify-center gap-4">
<svg
className="h-9 w-9 animate-spin text-black dark:text-white"
fill="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path
className="opacity-75 dark:opacity-100"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
fill="currentColor"
/>
</svg>
<div className="text-lg font-medium">Loading...</div>
</div>
);
}

View File

@@ -1,16 +0,0 @@
import Link from 'next/link';
export default function NotFound() {
return (
<div className="mx-auto max-w-lg min-h-screen flex flex-col place-content-center place-items-center gap-8 px-8 py-16 lg:px-6 lg:py-0">
<h1 className="text-[9rem] font-black leading-none md:text-[12rem]">404</h1>
<h2 className="text-[2rem] md:text-[3rem]">Not found.</h2>
<Link
className="h-11 flex flex-row transform-gpu cursor-pointer select-none appearance-none place-items-center border-0 rounded bg-blurple px-6 text-base text-white font-semibold leading-none no-underline outline-none active:translate-y-px focus:ring focus:ring-width-2 focus:ring-white"
href="/guide"
>
Take me back
</Link>
</div>
);
}

View File

@@ -1,3 +1,5 @@
export default function Page() {
return null;
import { redirect } from 'next/navigation';
export default async function Page() {
redirect('/guide');
}

View File

@@ -1,8 +0,0 @@
'use client';
import { ThemeProvider } from 'next-themes';
import type { PropsWithChildren } from 'react';
export function Providers({ children }: PropsWithChildren) {
return <ThemeProvider attribute="class">{children}</ThemeProvider>;
}

Binary file not shown.

View File

@@ -1,91 +0,0 @@
import { FiExternalLink } from '@react-icons/all-files/fi/FiExternalLink';
import type { PropsWithChildren } from 'react';
import {
BASE_URL_DISCORD_API_TYPES,
DISCORD_API_TYPES_VERSION,
DISCORD_API_TYPES_VOICE_VERSION,
} from '~/util/constants';
interface DiscordAPITypesLinkOptions {
/**
* The initial documentation enum, interface, function etc.
*
* @example `'RESTJSONErrorCodes'`
*/
readonly parent?: string;
/**
* The scope of where this link lives.
*
* @remarks API does not have a scope.
*/
readonly scope?: 'gateway' | 'globals' | 'payloads' | 'rest' | 'rpc' | 'utils' | 'voice';
/**
* The symbol belonging to the parent.
*
* @example '`MaximumNumberOfGuildsReached'`
*/
readonly symbol?: string;
/**
* The type of the {@link DiscordAPITypesLinkOptions.parent}.
*
* @example `'enum'`
* @example `'interface'`
*/
readonly type?: string;
}
export function DiscordAPITypesLink({
parent,
scope,
symbol,
type,
children,
}: PropsWithChildren<DiscordAPITypesLinkOptions>) {
let url = BASE_URL_DISCORD_API_TYPES;
let text = 'discord-api-types';
if (type || parent) {
url += `/api/discord-api-types`;
switch (scope) {
case 'globals':
url += `-${scope}`;
break;
case 'gateway':
case 'payloads':
case 'rest':
url += `-${scope}/common`;
break;
case 'rpc':
case 'utils':
url += `-${scope}/${DISCORD_API_TYPES_VERSION}`;
break;
case 'voice':
url += `-${scope}/${DISCORD_API_TYPES_VOICE_VERSION}`;
break;
default:
url += `-${DISCORD_API_TYPES_VERSION}`;
}
if (type) {
url += `/${type}/${parent}`;
if (symbol) url += `#${symbol}`;
} else {
url += `#${parent}`;
}
text = `${parent}${symbol ? `#${symbol}` : ''}${type?.toUpperCase() === 'FUNCTION' ? '()' : ''}`;
}
return (
<a
className="inline-flex flex-row place-items-center gap-1"
href={url}
rel="external noopener noreferrer"
target="_blank"
>
{children ?? text}
<FiExternalLink size={18} />
</a>
);
}

View File

@@ -1,86 +0,0 @@
import { FiExternalLink } from '@react-icons/all-files/fi/FiExternalLink';
import type { PropsWithChildren } from 'react';
import { BASE_URL, BASE_URL_LEGACY, PACKAGES, VERSION } from '~/util/constants';
interface DocsLinkOptions {
/**
* Whether to apply brackets to the end of the symbol to denote a method.
*
* @remarks Functions automatically infer this.
*/
readonly brackets?: boolean;
/**
* The package.
*
* @defaultValue `'discord.js'`
*/
readonly package?: (typeof PACKAGES)[number];
/**
* The initial documentation class, function, interface etc.
*
* @example `'Client'`
*/
readonly parent?: string;
/**
* Whether to reference a static property.
*
* @remarks
* This should only be used for the https://discord.js.org domain
* as static properties are not identified in the URL.
*/
readonly static?: boolean;
/**
* The symbol belonging to the parent.
*
* @example '`login'`
*/
readonly symbol?: string;
/**
* The type of the {@link DocsLinkOptions.parent}.
*
* @example `'class'`
* @example `'Function'`
*/
readonly type?: string;
}
export function DocsLink({
package: docs = PACKAGES[0],
type,
parent,
symbol,
brackets,
static: staticReference,
children,
}: PropsWithChildren<DocsLinkOptions>) {
// In the case of no type and no parent, this will default to the entry point of the respective documentation.
let url = docs === PACKAGES[0] ? `${BASE_URL_LEGACY}/${VERSION}/general/welcome` : `${BASE_URL}/${docs}/stable`;
let text = `${docs === PACKAGES[0] ? '' : '@discordjs/'}${docs}`;
// If there is a type and parent, we need to do some parsing.
if (type && parent) {
const bracketText = brackets || type?.toUpperCase() === 'FUNCTION' ? '()' : '';
// Legacy discord.js documentation parsing.
if (docs === PACKAGES[0]) {
url = `${BASE_URL_LEGACY}/${VERSION}/${type}/${parent}`;
if (symbol) url += `?scrollTo=${symbol}`;
text = `${parent}${symbol ? (symbol.startsWith('s-') ? '.' : '#') : ''}${
// eslint-disable-next-line prefer-named-capture-group
symbol ? `${symbol.replace(/(e|s)-/, '')}` : ''
}${bracketText}`;
} else {
url += `/${parent}:${type}`;
if (symbol) url += `#${symbol}`;
text = `${parent}${symbol ? `${staticReference ? '.' : '#'}${symbol}` : ''}${bracketText}`;
}
}
return (
<a className="inline-flex flex-row place-items-center gap-1" href={url} rel="noopener noreferrer" target="_blank">
{children ?? text}
<FiExternalLink size={18} />
</a>
);
}

View File

@@ -1,98 +0,0 @@
import Image from 'next/image';
import vercelLogo from '~/assets/powered-by-vercel.svg';
import workersLogo from '~/assets/powered-by-workers.png';
export default function Footer() {
return (
<footer className="md:pl-12 md:pr-12">
<div className="flex flex-col flex-wrap place-content-center gap-6 pt-12 sm:flex-row md:gap-12">
<div className="flex flex-wrap place-content-center place-items-center gap-4">
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"
rel="external noopener noreferrer"
target="_blank"
title="Vercel"
>
<Image
alt="Vercel"
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAABLCAQAAAA1k5H2AAAAi0lEQVR42u3SMQEAAAgDoC251a3gL2SgmfBYBRAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARCAgwWEOSWBnYbKggAAAABJRU5ErkJggg=="
height={44}
placeholder="blur"
src={vercelLogo}
width={212}
/>
</a>
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://www.cloudflare.com"
rel="external noopener noreferrer"
target="_blank"
title="Cloudflare Workers"
>
<Image
alt="Cloudflare"
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAABLCAQAAAA1k5H2AAAAi0lEQVR42u3SMQEAAAgDoC251a3gL2SgmfBYBRAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARAAARCAgwWEOSWBnYbKggAAAABJRU5ErkJggg=="
height={44}
placeholder="blur"
priority
src={workersLogo}
/>
</a>
</div>
<div className="flex flex-col place-self-center gap-6 sm:flex-row md:gap-12">
<div className="max-w-max flex flex-col gap-2">
<div className="text-lg font-semibold">Community</div>
<div className="flex flex-col gap-1">
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://discord.gg/djs"
rel="external noopener noreferrer"
target="_blank"
>
Discord
</a>
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://github.com/discordjs/discord.js/discussions"
rel="external noopener noreferrer"
target="_blank"
>
GitHub discussions
</a>
</div>
</div>
<div className="max-w-max flex flex-col gap-2">
<div className="text-lg font-semibold">Project</div>
<div className="flex flex-col gap-1">
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://github.com/discordjs/discord.js"
rel="external noopener noreferrer"
target="_blank"
>
discord.js
</a>
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://discord.js.org/docs"
rel="noopener noreferrer"
target="_blank"
>
discord.js documentation
</a>
<a
className="rounded outline-none focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://discord-api-types.dev"
rel="external noopener noreferrer"
target="_blank"
>
discord-api-types
</a>
</div>
</div>
</div>
</div>
</footer>
);
}

View File

@@ -1,9 +0,0 @@
import type { HTMLAttributes, PropsWithChildren } from 'react';
export function H1({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLHeadingElement>>) {
return (
<h1 className={`group ${className}`} {...props}>
{children}
</h1>
);
}

View File

@@ -1,9 +0,0 @@
import type { HTMLAttributes, PropsWithChildren } from 'react';
export function H2({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLHeadingElement>>) {
return (
<h2 className={`group ${className}`} {...props}>
{children}
</h2>
);
}

View File

@@ -1,9 +0,0 @@
import type { HTMLAttributes, PropsWithChildren } from 'react';
export function H3({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLHeadingElement>>) {
return (
<h3 className={`group ${className}`} {...props}>
{children}
</h3>
);
}

View File

@@ -1,9 +0,0 @@
import type { HTMLAttributes, PropsWithChildren } from 'react';
export function H4({ children, className, ...props }: PropsWithChildren<HTMLAttributes<HTMLHeadingElement>>) {
return (
<h4 className={`group ${className}`} {...props}>
{children}
</h4>
);
}

View File

@@ -1,92 +0,0 @@
'use client';
import { VscGithubInverted } from '@react-icons/all-files/vsc/VscGithubInverted';
import { VscMenu } from '@react-icons/all-files/vsc/VscMenu';
import { Button } from 'ariakit/button';
import type { Route } from 'next';
import dynamic from 'next/dynamic';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { Fragment, useMemo } from 'react';
import { useNav } from '~/contexts/nav';
const ThemeSwitcher = dynamic(async () => import('./ThemeSwitcher'));
export default function Header() {
const pathname = usePathname();
const { setOpened } = useNav();
const pathElements = useMemo(
() =>
pathname
.split('/')
.slice(1)
.map((path, idx, original) => (
<Link
className="rounded outline-none hover:underline focus:ring focus:ring-width-2 focus:ring-blurple"
href={`/${original.slice(0, idx + 1).join('/')}` as Route}
key={`${path}-${idx}`}
>
{path}
</Link>
)),
[pathname],
);
const breadcrumbs = useMemo(
() =>
pathElements.flatMap((el, idx, array) => {
if (idx === 0) {
return (
<Fragment key={`${el.key}-${idx}`}>
<div className="mx-2">/</div>
<div>{el}</div>
<div className="mx-2">/</div>
</Fragment>
);
}
if (idx !== array.length - 1) {
return (
<Fragment key={`${el.key}-${idx}`}>
<div>{el}</div>
<div className="mx-2">/</div>
</Fragment>
);
}
return <div key={`${el.key}-${idx}`}>{el}</div>;
}),
[pathElements],
);
return (
<header className="sticky top-4 z-20 border border-light-900 rounded-md bg-white/75 shadow backdrop-blur-md dark:border-dark-100 dark:bg-dark-600/75">
<div className="block h-16 px-6">
<div className="h-full flex flex-row place-content-between place-items-center gap-8">
<Button
aria-label="Menu"
className="h-6 w-6 flex flex-row transform-gpu cursor-pointer select-none appearance-none place-items-center border-0 rounded bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-none lg:hidden active:translate-y-px focus:ring focus:ring-width-2 focus:ring-blurple"
onClick={() => setOpened((open) => !open)}
>
<VscMenu size={24} />
</Button>
<div className="hidden lg:flex lg:grow lg:flex-row lg:overflow-hidden">{breadcrumbs}</div>
<div className="flex flex-row place-items-center gap-4">
<Button
aria-label="GitHub"
as="a"
className="h-6 w-6 flex flex-row transform-gpu cursor-pointer select-none appearance-none place-items-center border-0 rounded rounded-full bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-none active:translate-y-px focus:ring focus:ring-width-2 focus:ring-blurple"
href="https://github.com/discordjs/discord.js"
rel="external noopener noreferrer"
target="_blank"
>
<VscGithubInverted size={24} />
</Button>
<ThemeSwitcher />
</div>
</div>
</div>
</header>
);
}

View File

@@ -1,34 +0,0 @@
'use client';
import { Alert, Section, DiscordMessages, DiscordMessage, DiscordMessageEmbed } from '@discordjs/ui';
import { useMDXComponent } from 'next-contentlayer/hooks';
import { DocsLink } from '~/components/DocsLink';
import { ResultingCode } from '~/components/ResultingCode';
import { DiscordAPITypesLink } from './DiscordAPITypesLink';
import { H1 } from './H1';
import { H2 } from './H2';
import { H3 } from './H3';
import { H4 } from './H4';
export function Mdx({ code }: { readonly code: string }) {
const Component = useMDXComponent(code);
return (
<Component
components={{
Alert,
Section,
DiscordMessages,
DiscordMessage,
DiscordMessageEmbed,
DiscordAPITypesLink,
DocsLink,
ResultingCode,
h1: H1,
h2: H2,
h3: H3,
h4: H4,
}}
/>
);
}

View File

@@ -1,32 +0,0 @@
'use client';
import { Scrollbars } from 'react-custom-scrollbars-2';
import { useNav } from '~/contexts/nav';
import { Sidebar } from './Sidebar';
export function Nav() {
const { opened } = useNav();
return (
<nav
className={`dark:bg-dark-600/75 dark:border-dark-100 border-light-900 top-22 fixed bottom-4 left-4 right-4 z-20 mx-auto max-w-5xl rounded-md border bg-white/75 shadow backdrop-blur-md ${
opened ? 'block' : 'hidden'
} lg:min-w-xs lg:sticky lg:block lg:h-full lg:w-full lg:max-w-xs`}
>
<Scrollbars
autoHide
className="[&>div]:overscroll-none"
hideTracksWhenNotNeeded
renderThumbVertical={(props) => <div {...props} className="z-30 rounded bg-light-900 dark:bg-dark-100" />}
renderTrackVertical={(props) => (
<div {...props} className="absolute bottom-0.5 right-0.5 top-0.5 z-30 w-1.5 rounded" />
)}
universal
>
<div className="flex flex-col gap-4 p-3">
<Sidebar />
</div>
</Scrollbars>
</nav>
);
}

View File

@@ -1,69 +0,0 @@
import { useMemo, useState } from 'react';
import { Scrollbars } from 'react-custom-scrollbars-2';
const LINK_HEIGHT = 30;
const INDICATOR_SIZE = 10;
const INDICATOR_OFFSET = (LINK_HEIGHT - INDICATOR_SIZE) / 2;
export function Outline({ headings }: { readonly headings: any[] }) {
// eslint-disable-next-line react/hook-use-state
const [active /* setActive */] = useState(0);
const headingItems = useMemo(
() =>
headings.map((heading, idx) => (
<a
className={`dark:border-dark-100 border-light-800 pl-6.5 focus:ring-width-2 focus:ring-blurple ml-[10px] border-l p-[5px] text-sm outline-none focus:rounded focus:border-0 focus:ring ${
idx === active
? 'bg-blurple text-white'
: 'dark:hover:bg-dark-200 dark:active:bg-dark-100 hover:bg-light-700 active:bg-light-800'
}`}
href={`#${heading.slug}`}
key={heading.slug}
style={{ paddingLeft: `${heading.depth * 14}px` }}
title={heading.text}
>
<span className="line-clamp-1">{heading.text}</span>
</a>
)),
[headings, active],
);
// useEffect(() => {
// const idx = headings.findIndex((heading) => heading.slug === state.hash?.slice(1));
// if (idx >= 0) {
// setActive(idx);
// }
// }, [state, headings]);
return (
<Scrollbars
autoHide
hideTracksWhenNotNeeded
renderThumbVertical={(props) => <div {...props} className="z-30 rounded bg-light-900 dark:bg-dark-100" />}
renderTrackVertical={(props) => (
<div {...props} className="absolute bottom-0.5 right-0.5 top-0.5 z-30 w-1.5 rounded" />
)}
universal
>
<div className="flex flex-col break-all p-3 pb-8">
<div className="ml-2 mt-4 flex flex-row gap-2">
{/* <VscListSelection size={25} /> */}
<span className="font-semibold">Contents</span>
</div>
<div className="ml-2 mt-4 flex flex-col gap-2">
<div className="relative flex flex-col">
<div
className="absolute h-[10px] w-[10px] border-2 border-black rounded-full bg-blurple dark:border-white"
style={{
left: INDICATOR_SIZE / 2 + 0.5,
transform: `translateY(${active * LINK_HEIGHT + INDICATOR_OFFSET}px)`,
}}
/>
{headingItems}
</div>
</div>
</div>
</Scrollbars>
);
}

View File

@@ -1,21 +0,0 @@
export function PageButton({
url,
title,
direction,
}: {
readonly direction: 'next' | 'prev';
readonly title: string;
readonly url: string;
}) {
return (
<a
className="flex flex-row flex-col transform-gpu cursor-pointer select-none appearance-none place-items-center gap-2 rounded bg-light-600 px-4 py-3 leading-none no-underline outline-none active:translate-y-px active:bg-light-800 dark:bg-dark-600 hover:bg-light-700 focus:ring focus:ring-width-2 focus:ring-blurple dark:active:bg-dark-400 dark:hover:bg-dark-500"
href={url}
>
<h3 className="text-md font-semibold">{title}</h3>
<p className={`${direction === 'next' ? 'ml-auto' : 'mr-auto'} text-sm text-gray-600 dark:text-gray-400`}>
{direction === 'next' ? 'Next Page' : 'Previous Page'}
</p>
</a>
);
}

View File

@@ -1,3 +0,0 @@
export function ResultingCode() {
return null;
}

View File

@@ -1,8 +0,0 @@
'use client';
import { Section as DJSSection, type SectionOptions } from '@discordjs/ui';
import type { PropsWithChildren } from 'react';
export function Section(options: PropsWithChildren<SectionOptions>) {
return <DJSSection {...options} />;
}

View File

@@ -1,63 +0,0 @@
'use client';
import type { Route } from 'next';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { allContents } from 'contentlayer/generated';
import { useNav } from '~/contexts/nav';
import { Section } from './Section';
const items = allContents.map((content) => ({
title: content.title,
category: content.category,
slug: content.slug,
href: content.url,
}));
function transformItemsByCategory(allContents: typeof items) {
return allContents.reduce<Record<string, typeof items>>((accumulator: any, content) => {
if (!accumulator[content.category]) {
accumulator[content.category] = [];
}
accumulator[content.category].push(content);
return accumulator;
}, {});
}
const itemsByCategory = transformItemsByCategory(items);
export function Sidebar() {
const pathname = usePathname();
const { setOpened } = useNav();
return (
<div className="flex flex-col gap-4">
{Object.keys(itemsByCategory).map((category, idx) => (
<Section
buttonClassName="bg-light-600 hover:bg-light-700 active:bg-light-800 dark:bg-dark-400 dark:hover:bg-dark-300 dark:active:bg-dark-400 focus:ring-width-2 focus:ring-blurple rounded p-3 outline-none focus:ring z-10"
key={`${category}-${idx}`}
title={category}
>
{itemsByCategory[category]?.map((member, index) => (
<Link
className={`dark:border-dark-100 border-light-800 focus:ring-width-2 focus:ring-blurple ml-5 flex flex-col border-l first:mt-1 p-[5px] pl-6 outline-none focus:rounded focus:border-0 focus:ring ${
decodeURIComponent(pathname ?? '') === member.href
? 'bg-blurple text-white'
: 'dark:hover:bg-dark-200 dark:active:bg-dark-100 hover:bg-light-700 active:bg-light-800'
}`}
href={member.href as Route}
key={`${member.title}-${index}`}
onClick={() => setOpened(false)}
title={member.title}
>
<div className="flex flex-row place-items-center gap-2 lg:text-sm">
<span className="truncate">{member.title}</span>
</div>
</Link>
))}
</Section>
))}
</div>
);
}

View File

@@ -1,20 +0,0 @@
'use client';
import { VscColorMode } from '@react-icons/all-files/vsc/VscColorMode';
import { Button } from 'ariakit/button';
import { useTheme } from 'next-themes';
export default function ThemeSwitcher() {
const { resolvedTheme, setTheme } = useTheme();
const toggleTheme = () => setTheme(resolvedTheme === 'light' ? 'dark' : 'light');
return (
<Button
aria-label="Toggle theme"
className="h-6 w-6 flex flex-row transform-gpu cursor-pointer select-none appearance-none place-items-center border-0 rounded rounded-full bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-none active:translate-y-px focus:ring focus:ring-width-2 focus:ring-blurple"
onClick={() => toggleTheme()}
>
<VscColorMode size={24} />
</Button>
);
}

View File

@@ -1,32 +0,0 @@
---
title: Introduction
category: Home
---
# Introduction
If you're reading this, it probably means you want to learn how to make a bot with discord.js. Awesome! You've come to the right place.
This guide will teach you things such as:
- How to get a bot [up and running](../getting-started/starting-out) from scratch;
- In-depth explanations regarding features and concepts of the API (e.g. [intents](../topics/intents), [threads](../topics/threads), [webhooks](../topics/webhooks));
- And much more.
This guide will also cover subjects like common errors and how to solve them, keeping your code clean, setting up a proper development environment, etc.
Sounds good? Great! Let's get started.
## Before you begin...
Alright, making a bot is cool and all, but there are some prerequisites to it. To create a bot with discord.js, you should have a fairly decent grasp of JavaScript itself.
While you _can_ make a bot with very little JavaScript and programming knowledge, trying to do so without understanding the language first will only hinder you. You may get stuck on many uncomplicated issues, struggle with solutions to incredibly easy problems, and all-in-all end up frustrated. Sounds pretty annoying.
If you don't know JavaScript but would like to learn about it, here are a few links to help get you started:
- [Eloquent JavaScript, a free online book](http://eloquentjavascript.net)
- [JavaScript.info, a modern javascript tutorial](https://javascript.info)
- [Codecademy's interactive JavaScript course](https://codecademy.com/learn/introduction-to-javascript)
- [Nodeschool, for both JavaScript and Node.js lessons](https://nodeschool.io)
- [MDN's JavaScript guide and full documentation](https://developer.mozilla.org/docs/Web/JavaScript)
- [Google, your best friend](https://google.com)
Take your pick, learn some JavaScript, and once you feel like you're confident enough to make a bot, come back and get started!

View File

@@ -1,49 +0,0 @@
---
title: What's new
category: Home
---
# What's new
<DiscordMessages rounded>
<DiscordMessage
interaction={{
author: {
avatar: '/assets/old-guide.png',
username: 'discord.js',
},
command: '/upgrade',
}}
author={{
avatar: '/assets/discordjs.png',
bot: true,
username: 'Guide Bot',
time: 'Today at 21:00',
}}
>
This website is new! We will no longer be updating the old guide website.
</DiscordMessage>
</DiscordMessages>
## Site
We have moved from VuePress to [Next.js](https://nextjs.org/)! The source can be found [here](https://github.com/discordjs/discord.js/tree/main/apps/guide).
## Pages
- Pages have been revamped to account for our new [create-discord-bot](https://github.com/discordjs/discord.js/tree/main/packages/create-discord-bot) command-line interface.
- Popular topic are now simply "topics" that detail usage of a particular concept of the API.
- Focus is primarily on discord.js, so irrelevant topics have been removed. It may be better to visit the documentation of the package you are using to learn how to use them.
<DiscordMessages rounded>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
username: 'Guide Bot',
time: 'Today at 21:00',
}}
>
Thank you to all of those that contributed to the development of discord.js and the guide!
</DiscordMessage>
</DiscordMessages>

View File

@@ -1,198 +0,0 @@
---
title: How to contribute
category: Home
---
# How to contribute
Since this guide is made specifically for the discord.js community, we want to be sure to provide the most relevant and up-to-date content. We will, of course, make additions to the current pages and add new ones as we see fit, but fulfilling requests is how we know we're providing content you all want the most.
Requests may be as simple as "add an example to the [frequently asked questions](../topics/frequently-asked-questions) page", or as elaborate as "add a page regarding [sharding](../topics/sharding)". We'll do our best to fulfill all requests, as long as they're reasonable.
To make a request, simply head over to [the repository's issue tracker](https://github.com/discordjs/discord.js/issues) and [create a new issue](https://github.com/discordjs/discord.js/issues/new)! Title it appropriately, and let us know exactly what you mean inside the issue description. Make sure that you've looked around the site before making a request; what you want to request might already exist!
<Alert title="Tip" type="info">
Remember that you can always [fork the repository](https://github.com/discordjs/discord.js/fork) and [make a pull
request](https://github.com/discordjs/discord.js/pulls) if you want to add anything to the guide yourself!
</Alert>
We'll also get into some of the more advanced features this guide uses below. We recommended you have a look at the [source](https://github.com/discordjs/discord.js/blob/main/apps/guide/src/content/01-home/03-how-to-contribute.mdx) of this page to see exactly how they work.
## Components
Throughout the guide, you'll see some components from the _`@discordjs/ui`_ package:
- _`Alert`_
- _`Section`_
- _`DiscordMessages`_, _`DiscordMessage`_, and _`DiscordMessageEmbed`_
Check the source of this page to see them in action!
### Alert
This component may take a _`title`_ and a _`type`_ of _`'danger' | 'info' | 'success' | 'warning'`_.
This uses _`title="Alert" type="info"`_:
<Alert title="Alert" type="info">
Use these appropriately!
</Alert>
### Section
<Section title="Expand me!" padding defaultClosed background gutter>
Well, hello there!
Whenever some text does not need to be in the main body, you can put it here.
- _`title`_: The title that'll appear.
- _`padding`_: Adds padding.
- _`dense`_: When _`padding`_ is specified, _`dense`_ could make it appear, well, dense.
- _`defaultClosed`_ Whether the section is closed by default. This one was.
- _`background`_ Adds background to the content.
- _`gutter`_: This adds a very small appealing space between the expansion of the section and its content.
</Section>
### DiscordMessages, DiscordMessage, and DiscordMessageEmbed
<DiscordMessages>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
time: 'Today at 21:00',
username: 'Guide Bot',
}}
>
A _`DiscordMessage`_ must be within _`DiscordMessages`_.
</DiscordMessage>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
time: 'Today at 21:01',
username: 'Guide Bot',
}}
reply={{
author: {
avatar: '/assets/discordjs.png',
bot: true,
username: 'Guide Bot',
},
content: 'A _`DiscordMessage`_ must be within _`DiscordMessages`_.',
}}
time="21:02"
>
It's much better to see the source code of this page to replicate and learn!
</DiscordMessage>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
time: 'Today at 21:02',
username: 'Guide Bot',
}}
>
This message depicts the use of embeds.
<>
<DiscordMessageEmbed
author={{
avatar: '/assets/discordjs.png',
username: 'Guide Bot',
}}
footer={{ content: 'Sometimes, titles just have to be.' }}
title={{ title: 'An amazing title' }}
>
This is a description. You can put a description here. It must be descriptive!
</DiscordMessageEmbed>
<DiscordMessageEmbed
author={{
avatar: '/assets/discordjs.png',
username: 'Guide Bot',
}}
footer={{ content: "When one amazing title just wasn't enough." }}
title={{ title: 'Another amazing title' }}
>
Multiple embeds!
</DiscordMessageEmbed>
</>
</DiscordMessage>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
time: 'Today at 21:03',
username: 'Guide Bot',
}}
interaction={{
author: {
avatar: '/assets/discordjs.png',
bot: true,
username: 'Guide Bot',
},
command: '/interaction',
}}
>
Interactions are supported! I definitely used a command.
</DiscordMessage>
<DiscordMessage
author={{
avatar: '/assets/discordjs.png',
bot: true,
color: 'text-red-500',
time: 'Today at 21:04',
username: 'Guide Bot',
}}
reply={{
author: {
avatar: '/assets/snek-bot.jpeg',
bot: true,
verified: true,
color: 'text-blue-500',
username: 'Snek Bot',
},
content: 'You can also have verified bots, like me!',
}}
>
Display colors are supported as well!
</DiscordMessage>
</DiscordMessages>
## Code blocks
We use [Code Hike](https://codehike.org). Here are some example code blocks, which should be easy to grasp and learn upon reading the source code of this page:
<CH.Code>
```ts
const HELLO = 'hello' as const;
console.log(HELLO);
// "ts" is the language of the code block.
```
</CH.Code>
<CH.Code>
```ts fileName
const FILE_NAME = 'fileName' as const;
if (FILE_NAME.includes(' ')) throw new Error('Spaces cannot be used in file names.');
```
```ts anotherFileName
const FILE_NAME_2 = 'anotherFileName' as const;
// Putting code blocks together makes them appear in tabs, just like in your editor.
```
---
```ts requiredName
const FILE_NAME_3 = 'requiredName' as const;
if (!FILE_NAME) throw new Error('There must be a file name to use panels!');
// The --- divider was used to create a panel.
```
</CH.Code>
For more information, be sure to check out the [documentation](https://codehike.org/docs/ch-code).

View File

@@ -1,64 +0,0 @@
---
title: Starting out
category: Getting started
---
# Starting out
Our [create-discord-bot](https://github.com/discordjs/discord.js/tree/main/packages/create-discord-bot) command-line interface sets up a basic Discord bot to help you get started on your journey.
## Creating your bot
To use discord.js, you'll need to install [Node.js](https://nodejs.org), [Deno](https://deno.com), or [Bun](https://bun.sh). discord.js v14 requires Node.js v16.11.0 or higher, but the long-term support (LTS) version is always recommended. For the purposes of this guide, we will be using Node.js.
<Alert title="Tip" type="info">
To check if you already have Node.js installed, run _`node --version`_ in your terminal. If it outputs _`v16.11.0`_ or
higher, then you're good to go!
</Alert>
### Windows
- Download from the [Node.js website](https://nodejs.org).
- Use [fnm](https://github.com/Schniz/fnm).
- Use [Volta](https://volta.sh).
### macOS
- Download from the [Node.js website](https://nodejs.org/).
- Use [fnm](https://github.com/Schniz/fnm).
- Use [Homebrew](https://formulae.brew.sh/formula/node).
- Use [nvm](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating).
- Use [Volta](https://volta.sh).
### Linux
- Visit [this page](https://nodejs.org/en/download/package-manager) to determine how you should install Node.js.
- Use [fnm](https://github.com/Schniz/fnm).
- Use [nvm](https://github.com/nvm-sh/nvm).
- Use [Volta](https://volta.sh).
After installing Node.js, you'll be able to create a new application from your desired package manager. If you're starting out fresh, installing Node.js will also install npm, a package manager for Node.js.
<CH.Code lineNumbers={false} showCopyButton={true}>
```sh npm
npm create discord-bot
```
```sh yarn
yarn create discord-bot
```
```sh pnpm
pnpm create discord-bot
```
```sh bun
bun create discord-bot
```
</CH.Code>
You'll be asked the directory to create the application in, as well as whether TypeScript should be used. Dependencies will automatically be installed for you. After this, you've just got your startup Discord bot template _nearly_ ready!
In the next section, we will explain how to create an application to interact with Discord's API.

View File

@@ -1,64 +0,0 @@
---
title: Setting up an application
category: Getting started
---
# Setting up an application
You'll need to create an application on Discord's developer portal so your bot has a token to interact with Discord's API.
## Creating the application
Follow these steps:
1. Open the [Discord developer portal](https://discord.com/developers/applications). You'll need to be logged in.
2. Click on the "New Application" button.
3. Enter a name and confirm the pop-up window by clicking the "Create" button.
- You'll need to agree to the [Developer Terms of Service](https://discord.com/developers/docs/policies-and-agreements/terms-of-service) and [Developer Policy](https://discord.com/developers/docs/policies-and-agreements/developer-policy).
You should see a page like this:
![Successfully created application](/assets/create-app.png)
You can edit your application's name, description, and avatar here. Copy the application id and paste it in the .env file after _`APPLICATION_ID=`_.
Once you've saved your changes, move on by selecting the "Bot" tab in the left pane.
## Your bot's token
<Alert title="Important" type="danger">
This section is critical, so pay close attention. It explains what your bot token is, as well as the security aspects
of it.
</Alert>
On the bot tab, you'll see a section like this:
![Bot application](/assets/bot-user.png)
In this panel, you can give your bot a snazzy avatar, set its username, and make it public or private. Your bot's token will be revealed when you press the "Reset Token" button and confirm. Once you've done this, copy it and paste it in the .env file after _`DISCORD_TOKEN=`_.
If you happen to lose this token at some point, you will need to come back to this page and reset it, which will reveal the new token, invalidating all old ones.
### Bot token explanation
A token is essentially your bot's password; it's what your bot uses to login to Discord. With that said, **it is vital that you do not ever share this token with anybody, purposely or accidentally**. If someone does manage to get a hold of your bot's token, they can use your bot as if it were theirs—this means they can perform malicious acts with it.
Tokens look like this: _`NzkyNzE1NDU0MTk2MDg4ODQy.X-hvzA.Ovy4MCQywSkoMRRclStW4xAYK7I`_ (don't worry, we immediately reset this token before even posting it here!). If it's any shorter and looks more like this: _`kxbsDRU5UfAaiO7ar9GFMHSlmTwYaIYn`_, you copied your client secret instead. Make sure to copy the token if you want your bot to work!
### Token leak scenario
Let's imagine that you have a bot on over 1,000 servers, and it took you many, many months of coding and patience to get it on that amount. Your bot's token gets leaked somewhere, and now someone else has it. That person can:
- Spam every server your bot is on;
- DM spam as many users as possible;
- Delete as many channels as possible;
- Kick or ban as many server members as possible;
- Make your bot leave all of the servers it has joined;
All that and much, much more. Sounds pretty terrible, right? So make sure to keep your bot's token as safe as possible!
<Alert title="Compromised tokens" type="danger">
If your bot token has been compromised by committing it to a public repository, posting it in discord.js support etc.
or otherwise see your bot's token in danger, return to this page and press "Reset Token". This will invalidate all old
tokens belonging to your bot. Keep in mind that you will need to update your bot's token where you used it before.
</Alert>

View File

@@ -1,48 +0,0 @@
---
title: Adding your bot to a server
category: Getting started
---
# Adding your bot to a server
After you [set up an application](./setting-up-an-application), you'll notice it's not in any servers yet. So, how does that work?
Before you're able to see your bot in a server, you will need to add it by using an invite link.
## Bot invite links
The basic version of one such link looks like this:
<CH.Code lineNumbers={false}>
```
https://discord.com/api/oauth2/authorize?client_id=123456789012345678&permissions=0&scope=bot
```
</CH.Code>
The structure of the URL is quite simple:
- _`https://discord.com/api/oauth2/authorize`_ is Discord's standard structure for authorizing an OAuth2 application (such as your bot application) for entry to a Discord server.
- _`client_id=...`_ is to specify _which_ application you want to authorize. You'll need to replace this part with your client's id to create a valid invite link.
- _`permissions=...`_ describes the permissions that your bot will request to be granted by default upon joining the server you are adding it to.
- _`scope=bot`_ specifies that you want to add this application as a Discord bot with the ability to create slash commands.
<Alert title="Warning" type="warning">
If you get an error message saying "Bot requires a code grant", head over to your application's settings and disable
the "Requires OAuth2 Code Grant" option. You shouldn't enable this option unless you know why you need to.
</Alert>
## Creating and using your invite link
To create an invite link, head back to the [developer portal](https://discord.com/developers/applications), click on your bot application, and open the OAuth2 page.
In the sidebar, you'll find the URL generator. Select the _`bot`_ option. Once you select the _`bot`_ option, a list of permissions will appear, allowing you to configure the permissions your bot needs.
Grab the link via the "Copy" button and send it in a channel in Discord. Click on the link you just sent which should reveal this:
![Bot Authorization page](/assets/bot-auth-page.png)
Choose the server you want to add the bot to and click "Authorize". Congratulations! You've successfully added your bot to your Discord server.
At this point, you should have a Discord bot you created with [create-discord-bot](https://github.com/discordjs/discord.js/tree/main/packages/create-discord-bot) with your .env file populated and your Discord bot in a server. You are now ready to do what you like.

View File

@@ -1,496 +0,0 @@
---
title: Frequently asked questions
category: Topics
---
# Frequently asked questions
## Legend
- _`client`_ is a placeholder for the <DocsLink type="class" parent="Client" /> object:
_`const client = new Client({ intents: [GatewayIntentBits.Guilds] });`_.
- _`interaction`_ is a placeholder for the <DocsLink type="class" parent="BaseInteraction" />:
_`client.on(Events.InteractionCreate, interaction => { ... });`_.
- _`guild`_ is a placeholder for the <DocsLink type="class" parent="Guild" /> object:
_`interaction.guild`_ or _`client.guilds.cache.get('id')`_
- _`voiceChannel`_ is a placeholder for the <DocsLink type="class" parent="VoiceChannel" />:
_`interaction.member.voice.channel`_.
For a more detailed explanation of the notations commonly used in this guide, the docs, and the support server, see [here](/additional-info/notation.md).
## Administrative
### How do I ban a user?
<CH.Code>
```js
const user = interaction.options.getUser('target');
await guild.members.ban(user);
```
</CH.Code>
### How do I unban a user?
<CH.Code>
```js
const user = interaction.options.getUser('target');
await guild.members.unban(user);
```
</CH.Code>
<Alert title="Tip" type="info">
Discord validates and resolves user ids for users not on the server in user slash command options. To retrieve and use
the full structure from the resulting interaction, you can use the{' '}
<DocsLink type="class" parent="CommandInteractionOptionResolver" symbol="getUser" brackets /> method.
</Alert>
### How do I kick a guild member?
<CH.Code>
```js
const member = interaction.options.getMember('target');
await member.kick();
```
</CH.Code>
### How do I timeout a guild member?
<CH.Code>
```js
const member = interaction.options.getMember('target');
await member.timeout(60_000); // Timeout for one minute
```
</CH.Code>
<Alert title="Tip" type="info">
Timeout durations are measured by the millisecond. The maximum timeout duration you can set is 28 days. To remove a
timeout set on a member, pass _`null`_ instead of a timeout duration.
</Alert>
### How do I add a role to a guild member?
<CH.Code>
```js
const role = interaction.options.getRole('role');
const member = interaction.options.getMember('target');
await member.roles.add(role);
```
</CH.Code>
### How do I check if a guild member has a specific role?
<CH.Code>
```js
const role = interaction.options.getRole('role');
const member = interaction.options.getMember('target');
if (member.roles.cache.has(role.id) {
// ...
}
```
</CH.Code>
### How do I limit a command to a single user?
<CH.Code>
```js
if (interaction.user.id === 'id') {
// ...
}
```
</CH.Code>
## Bot Configuration and Utility
### How do I set my bot's username?
<CH.Code>
```js
await client.user.setUsername('username');
```
</CH.Code>
### How do I set my bot's avatar?
<CH.Code>
```js
await client.user.setAvatar('URL or path');
```
</CH.Code>
### How do I set my playing status?
<CH.Code>
```js
client.user.setActivity('activity');
```
</CH.Code>
### How do I set my status to "Watching/Listening to/Competing in ..."?
<CH.Code>
```js
import { ActivityType } from 'discord.js';
client.user.setActivity('activity', { type: ActivityType.Watching });
client.user.setActivity('activity', { type: ActivityType.Listening });
client.user.setActivity('activity', { type: ActivityType.Competing });
```
</CH.Code>
<Alert title="Tip" type="info">
If you would like to set your activity upon startup, you can use the{' '}
<DocsLink type="typedef" parent="ClientOptions" /> object to set the appropriate
<DocsLink type="typedef" parent="PresenceData" />.
</Alert>
### How do I make my bot display online/idle/dnd/invisible?
<CH.Code>
```js
client.user.setStatus('online');
client.user.setStatus('idle');
client.user.setStatus('dnd');
client.user.setStatus('invisible');
```
</CH.Code>
### How do I set both status and activity in one go?
<CH.Code>
```js
client.user.setPresence({ activities: [{ name: 'activity' }], status: 'idle' });
```
</CH.Code>
## Miscellaneous
### How do I send a message to a specific channel?
<CH.Code>
```js
const channel = client.channels.cache.get('id');
await channel.send('content');
```
</CH.Code>
### How do I create a post in a forum channel?
<Alert title="Tip" type="info">
Currently, the only way to get tag ids is programmatically through{' '}
<DocsLink type="class" parent="ForumChannel" symbol="availableTags" />.
</Alert>
<CH.Code>
```js
const channel = client.channels.cache.get('id');
await channel.threads.create({
name: 'Post name',
message: { content: 'Message content' },
appliedTags: ['tagId', 'anotherTagId'],
});
```
</CH.Code>
### How do I DM a specific user?
<CH.Code>
```js
await client.users.send('id', 'content');
```
</CH.Code>
<Alert title="Tip" type="info">
If you want to send a direct message to the user who sent the interaction, you can use _`interaction.user.send()`_.
</Alert>
### How do I mention a specific user in a message?
<CH.Code>
```js
const user = interaction.options.getUser('target');
await interaction.reply(`Hi, ${user}.`);
await interaction.followUp(`Hi, <@${user.id}>.`);
```
</CH.Code>
<Alert title="Tip" type="info">
Mentions in embeds may resolve correctly in embed titles, descriptions and field values but will never notify the
user. Other areas do not support mentions at all.
</Alert>
### How do I control which users and/or roles are mentioned in a message?
Controlling which mentions will send a ping is done via the _`allowedMentions`_ option, which replaces _`disableMentions`_.
This can be set as a default in <DocsLink type="typedef" parent="ClientOptions" />, and controlled per-message sent by your bot.
<CH.Code>
```js
new Client({ allowedMentions: { parse: ['users', 'roles'] } });
```
</CH.Code>
Even more control can be achieved by listing specific _`users`_ or _`roles`_ to be mentioned by id, e.g.:
<CH.Code>
```js
await channel.send({
content: '<@123456789012345678> <@987654321098765432> <@&102938475665748392>',
allowedMentions: { users: ['123456789012345678'], roles: ['102938475665748392'] },
});
```
</CH.Code>
### How do I prompt the user for additional input?
<CH.Code>
```js
await interaction.reply('Please enter more input.');
const filter = (m) => interaction.user.id === m.author.id;
try {
const messages = await interaction.channel.awaitMessages({ filter, time: 60000, max: 1, errors: ['time'] });
await interaction.followUp(`You've entered: ${messages.first().content}`);
} catch {
await interaction.followUp('You did not enter any input!');
}
```
</CH.Code>
<Alert title="Tip" type="info">
If you want to learn more about this syntax or other types of collectors, check out [this dedicated guide page for
collectors](/popular-topics/collectors.md)!
</Alert>
### How do I block a user from using my bot?
<CH.Code>
```js
const blockedUsers = ['id1', 'id2'];
client.on(Events.InteractionCreate, (interaction) => {
if (blockedUsers.includes(interaction.user.id)) return;
});
```
</CH.Code>
<Alert title="Tip" type="info">
You do not need to have a constant local variable like _`blockedUsers`_ above. If you have a database system that you
use to store ids of blocked users, you can query the database instead.
</Alert>
<CH.Code>
```js
client.on(Events.InteractionCreate, async (interaction) => {
const blockedUsers = await database.query('SELECT user_id FROM blocked_users;');
if (blockedUsers.includes(interaction.user.id)) return;
});
```
</CH.Code>
Note that this is just a showcase of how you could do such a check.
### How do I react to the message my bot sent?
<CH.Code>
```js
const sentMessage = await interaction.channel.send('My message to react to.');
// Unicode emoji
await sentMessage.react('👍');
// Custom emoji
await sentMessage.react('123456789012345678');
await sentMessage.react('<emoji:123456789012345678>');
await sentMessage.react('<a:emoji:123456789012345678>');
await sentMessage.react('emoji:123456789012345678');
await sentMessage.react('a:emoji:123456789012345678');
```
</CH.Code>
<Alert title="Tip" type="info">
If you want to learn more about reactions, check out [this dedicated guide on
reactions](/popular-topics/reactions.md)!
</Alert>
### How do I restart my bot with a command?
<CH.Code>
```js
process.exit();
```
</CH.Code>
<Alert title="Warning" type="warning">
_`process.exit()`_ will only kill your Node process, but when using [PM2](https://pm2.keymetrics.io/), it will restart
the process whenever it gets killed. You can read our guide on PM2 [here](/improving-dev-environment/pm2.md).
</Alert>
### What is the difference between a User and a GuildMember?
A User represents a global Discord user, and a GuildMember represents a Discord user on a specific server. That means only GuildMembers can have permissions, roles, and nicknames, for example, because all of these things are server-bound information that could be different on each server that the user is in.
### How do I find all online members of a guild?
<CH.Code>
```js
// First use guild.members.fetch to make sure all members are cached
const fetchedMembers = await guild.members.fetch({ withPresences: true });
const totalOnline = fetchedMembers.filter((member) => member.presence?.status === 'online');
// Now you have a collection with all online member objects in the totalOnline variable
console.log(`There are currently ${totalOnline.size} members online in this guild!`);
```
</CH.Code>
<Alert title="Warning" type="warning">
This only works correctly if you have the _`GuildPresences`_ intent enabled for your application and client. If you
want to learn more about intents, check out [this dedicated guide on intents](/popular-topics/intents.md)!
</Alert>
### How do I check which role was added/removed and for which member?
<CH.Code>
```js
// Start by declaring a guildMemberUpdate listener
// This code should be placed outside of any other listener callbacks to prevent listener nesting
client.on(Events.GuildMemberUpdate, (oldMember, newMember) => {
// If the role(s) are present on the old member object but no longer on the new one (i.e role(s) were removed)
const removedRoles = oldMember.roles.cache.filter((role) => !newMember.roles.cache.has(role.id));
if (removedRoles.size > 0) {
console.log(`The roles ${removedRoles.map((r) => r.name)} were removed from ${oldMember.displayName}.`);
}
// If the role(s) are present on the new member object but are not on the old one (i.e role(s) were added)
const addedRoles = newMember.roles.cache.filter((role) => !oldMember.roles.cache.has(role.id));
if (addedRoles.size > 0) {
console.log(`The roles ${addedRoles.map((r) => r.name)} were added to ${oldMember.displayName}.`);
}
});
```
</CH.Code>
### How do I check the bot's ping?
There are two common measurements for bot pings. The first, **websocket heartbeat**, is the average interval of a regularly sent signal indicating the healthy operation of the websocket connection the library receives events over:
<CH.Code>
```js
await interaction.reply(`Websocket heartbeat: ${client.ws.ping}ms.`);
```
</CH.Code>
<Alert title="Tip" type="info">
If you're using [sharding](/sharding/), a specific shard's heartbeat can be found on the WebSocketShard instance,
accessible at _`client.ws.shards.get(id).ping`_.
</Alert>
The second, **Roundtrip Latency**, describes the amount of time a full API roundtrip (from the creation of the command message to the creation of the response message) takes. You then edit the response to the respective value to avoid needing to send yet another message:
<CH.Code>
```js
const sent = await interaction.reply({ content: 'Pinging...', fetchReply: true });
await interaction.editReply(`Roundtrip latency: ${sent.createdTimestamp - interaction.createdTimestamp}ms`);
```
</CH.Code>
### Why do some emojis behave weirdly?
If you've tried using [the usual method of retrieving unicode emojis](./reactions.md#unicode-emojis), you may have noticed that some characters don't provide the expected results. Here's a short snippet that'll help with that issue. You can toss this into a file of its own and use it anywhere you need! Alternatively feel free to simply copy-paste the characters from below:
<CH.Code>
```js index.js
import { emojiCharacters } from './emojiCharacters.js';
console.log(emojiCharacters.a); // 🇦
console.log(emojiCharacters[10]); // 🔟
console.log(emojiCharacters['!']); // ❗
```
{/* prettier-ignore */}
```js emojiCharacters.js
export const emojiCharacters = {
a: '🇦', b: '🇧', c: '🇨', d: '🇩',
e: '🇪', f: '🇫', g: '🇬', h: '🇭',
i: '🇮', j: '🇯', k: '🇰', l: '🇱',
m: '🇲', n: '🇳', o: '🇴', p: '🇵',
q: '🇶', r: '🇷', s: '🇸', t: '🇹',
u: '🇺', v: '🇻', w: '🇼', x: '🇽',
y: '🇾', z: '🇿', 0: '0⃣', 1: '1⃣',
2: '2⃣', 3: '3⃣', 4: '4⃣', 5: '5⃣',
6: '6⃣', 7: '7⃣', 8: '8⃣', 9: '9⃣',
10: '🔟', '#': '#️⃣', '*': '*️⃣',
'!': '❗', '?': '❓',
};
```
</CH.Code>
<Alert title="Tip" type="info">
You can use the <kbd>⌃ Control</kbd> <kbd>⌘ Command</kbd> <kbd>Space</kbd> keyboard shortcut to open up an emoji picker that can be used for quick, easy access to all the Unicode emojis available to you.
On Windows, the shortcut is <kbd>⊞</kbd> <kbd>.</kbd>.
</Alert>

View File

@@ -1,165 +0,0 @@
---
title: Audit logs
category: Topics
---
# Audit logs
## A Quick Background
Audit logs are an excellent moderation tool offered by Discord to know what happened in a server and usually by whom. Making use of audit logs requires the _`ViewAuditLog`_ permission. Audit logs may be fetched on a server, or they may be received via the gateway event <DocsLink type="class" parent="Client" symbol="e-guildAuditLogEntryCreate"/> which requires the _`GuildModeration`_ intent.
There are quite a few cases where you may use audit logs. This guide will limit itself to the most common use cases. Feel free to consult the [relevant Discord API page](https://discord.com/developers/docs/resources/audit-log) for more information.
Keep in mind that these examples explore a straightforward case and are by no means exhaustive. Their purpose is to teach you how audit logs work, and expansion of these examples is likely needed to suit your specific use case.
## Fetching Audit Logs
Let's start by glancing at the <DocsLink type="class" parent="Guild" symbol="fetchAuditLogs" brackets /> method and how to work with it. Like many discord.js methods, it returns a [Promise](../additional-info/understanding-async-await) containing the <DocsLink type="class" parent="GuildAuditLogs"/> object. This object has one property, _`entries`_, which holds a [Collection](../additional-info/collections) of <DocsLink type="class" parent="GuildAuditLogsEntry"/> objects, and consequently, the information you want to retrieve.
Here is the most basic fetch to look at some entries.
<CH.Code>
```js
const fetchedLogs = await guild.fetchAuditLogs();
const firstEntry = fetchedLogs.entries.first();
```
</CH.Code>
Simple, right? Now, let's look at utilizing its options:
<CH.Code>
```js
import { AuditLogEvent } from 'discord.js';
const fetchedLogs = await guild.fetchAuditLogs({
type: AuditLogEvent.InviteCreate,
limit: 1,
});
const firstEntry = fetchedLogs.entries.first();
```
</CH.Code>
This will return the first entry where an invite was created. You used _`limit: 1`_ here to specify only one entry.
## Receiving Audit Logs
Audit logs may be received via the gateway event <DocsLink type="class" parent="Client" symbol="e-guildAuditLogEntryCreate"/>.
This is the best way to receive audit logs if you want to monitor them. As soon as an audit log entry is created,
your application will receive an instance of this event. A common use case is to find out _who_ did the action that
caused the audit log event to happen.
### Who deleted a message?
One of the most common use cases for audit logs is understanding who deleted a message in a Discord server. If a user deleted another user's message, you can find out who did that as soon as you receive the corresponding audit log event.
<Alert title="Tip" type="info">
Messages deleted by their author or bots (excluding bulk deletes) do not generate audit log entries.
</Alert>
<CH.Code>
```js JavaScript
import { AuditLogEvent, Events } from 'discord.js';
client.on(Events.GuildAuditLogEntryCreate, async (auditLog) => {
// Define your variables.
// The extra information here will be the channel.
const { action, extra: channel, executorId, targetId } = auditLog;
// Check only for deleted messages.
if (action !== AuditLogEvent.MessageDelete) return;
// Ensure the executor is cached.
const executor = await client.users.fetch(executorId);
// Ensure the author whose message was deleted is cached.
const target = await client.users.fetch(targetId);
// Log the output.
console.log(`A message by ${target.tag} was deleted by ${executor.tag} in ${channel}.`);
});
```
```ts TypeScript
import { AuditLogEvent, Events } from 'discord.js';
client.on(Events.GuildAuditLogEntryCreate, async (auditLog) => {
// Define your variables.
// The extra information here will be the channel.
const { action, extra: channel, executorId, targetId } = auditLog;
// Check only for deleted messages.
if (action !== AuditLogEvent.MessageDelete) return;
// Ensure the executor is cached. The id definitely exists.
const executor = await client.users.fetch(executorId!);
// Ensure the author whose message was deleted is cached. The id definitely exists.
const target = await client.users.fetch(targetId!);
// Log the output.
console.log(`A message by ${target.tag} was deleted by ${executor.tag} in ${channel}.`);
});
```
</CH.Code>
With this, you now have a very simple logger telling you who deleted a message authored by another person.
### Who kicked a user?
This is very similar to the example above.
<CH.Code>
```js JavaScript
import { AuditLogEvent, Events } from 'discord.js';
client.on(Events.GuildAuditLogEntryCreate, async (auditLog) => {
// Define your variables.
const { action, executorId, targetId } = auditLog;
// Check only for kicked users.
if (action !== AuditLogEvent.MemberKick) return;
// Ensure the executor is cached.
const executor = await client.users.fetch(executorId);
// Ensure the kicked guild member is cached.
const kickedUser = await client.users.fetch(targetId);
// Now you can log the output!
console.log(`${kickedUser.tag} was kicked by ${executor.tag}.`);
});
```
```ts TypeScript
import { AuditLogEvent, Events } from 'discord.js';
client.on(Events.GuildAuditLogEntryCreate, async (auditLog) => {
// Define your variables.
const { action, executorId, targetId } = auditLog;
// Check only for kicked users.
if (action !== AuditLogEvent.MemberKick) return;
// Ensure the executor is cached. The id definitely exists.
const executor = await client.users.fetch(executorId!);
// Ensure the kicked guild member is cached. The id definitely exists.
const kickedUser = await client.users.fetch(targetId!);
// Now you can log the output!
console.log(`${kickedUser.tag} was kicked by ${executor.tag}.`);
});
```
</CH.Code>
If you want to check who banned a user, it's the same example as above except the _`action`_ should be <DiscordAPITypesLink type="enum" parent="AuditLogEvent" symbol="MemberBanAdd" />. You can check the rest of the possible actions on this page.

View File

@@ -1,223 +0,0 @@
---
title: Collectors
category: Topics
---
# Collectors
## Message collectors
{/* prettier-ignore */}
<DocsLink type="class" parent="Collector">Collectors</DocsLink> are useful to enable your bot to obtain _additional_ input after the first command was sent. An example would be initiating a quiz, where the bot will "await" a correct response from somebody.
### Basic message collector
Let's take a look at a basic message collector:
<CH.Code>
```js
const collectorFilter = (message) => message.content.includes('discord');
const collector = interaction.channel.createMessageCollector({ filter: collectorFilter, time: 15_000 });
collector.on('collect', (message) => {
console.log(`Collected ${message.content}`);
});
collector.on('end', (collected) => {
console.log(`Collected ${collected.size} messages`);
});
```
</CH.Code>
You can provide a _`filter`_ key to the object parameter of <DocsLink type="class" parent="TextChannel" symbol="createMessageCollector" brackets />. The value to this key should be a function that returns a boolean value to indicate if this message should be collected or not. To check for multiple conditions in your filter you can connect them using [logical operators](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Expressions_and_Operators#logical_operators). If you don't provide a filter all messages in the channel the collector was started on will be collected.
Note that the above example uses [implicit return](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions#function_body) for the filter function and passes it to the options object using the [object property shorthand](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer#property_definitions) notation.
If a message passes through the filter, it will trigger the <DocsLink type="class" parent="Collector" symbol="e-collect" /> event for the _`collector`_ you've created. This message is then passed into the event listener as _`collected`_ and the provided function is executed. In the above example, you simply log the message. Once the collector finishes collecting based on the provided end conditions the <DocsLink type="class" parent="Collector" symbol="e-end" /> event emits.
You can control when a collector ends by supplying additional option keys when creating a collector:
- _`time`_: Amount of time in milliseconds the collector should run for
- _`max`_: Number of messages to successfully pass the filter
- _`maxProcessed`_: Number of messages encountered (no matter the filter result)
The benefit of using an event-based collector over _`awaitMessages()`_ (its promise-based counterpart) is that you can do something directly after each message is collected, rather than just after the collector ended. You can also stop the collector manually by calling <DocsLink type="class" parent="Collector" symbol="stop" brackets />.
### Await messages
Using <DocsLink type="class" parent="TextChannel" symbol="awaitMessages" brackets /> can be easier if you understand [Promises](../additional-info/understanding-async-await), and it allows you to have cleaner code overall. It is essentially identical to <DocsLink type="class" parent="TextChannel" symbol="createMessageCollector" brackets />, except promisified. However, the drawback of using this method is that you cannot do things before the Promise is resolved or rejected, either by an error or completion. However, it should do for most purposes, such as awaiting the correct response in a quiz. Instead of taking their example, let's set up a basic quiz command using the _`.awaitMessages()`_ feature.
First, you'll need some questions and answers to choose from, so here's a basic set:
<CH.Code>
```json
[
{
"question": "What color is the sky?",
"answers": ["blue"]
},
{
"question": "How many letters are there in the alphabet?",
"answers": ["26", "twenty-six", "twenty six", "twentysix"]
}
]
```
</CH.Code>
The provided set allows for responder error with an array of answers permitted. Ideally, it would be best to place this in a JSON file, which you can call _`quiz.json`_ for simplicity.
<CH.Code>
```js
import quiz from './quiz.json' assert { type: 'json' };
// ...
const item = quiz[Math.floor(Math.random() * quiz.length)];
const collectorFilter = (response) => {
return item.answers.some((answer) => answer.toLowerCase() === response.content.toLowerCase());
};
await interaction.reply({ content: item.question });
try {
const collected = await interaction.channel.awaitMessages({
filter: collectorFilter,
max: 1,
time: 30_000,
errors: ['time'],
});
await interaction.followUp(`${collected.first().author} got the correct answer!`);
} catch {
await interaction.followUp('Looks like nobody got the answer this time.');
}
```
</CH.Code>
<Alert title="Tip" type="info">
If you don't understand how _`.some()`_ works, you can read about it in more detail
[here](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/some).
</Alert>
In this filter, you iterate through the answers to find what you want. You would like to ignore the case because simple typos can happen, so you convert each answer to its lowercase form and check if it's equal to the response in lowercase form as well. In the options section, you only want to allow one answer to pass through, hence the _`max: 1`_ setting.
The filter looks for messages that match one of the answers in the array of possible answers to pass through the collector. The _`max`_ option (the second parameter) specifies that only a maximum of one message can go through the filter successfully before the Promise successfully resolves. The _`errors`_ section specifies that time will cause it to error out, which will cause the Promise to reject if one correct answer is not received within the time limit of one minute. As you can see, there is no _`collect`_ event, so you are limited in that regard.
## Reaction collectors
### Basic reaction collector
These work quite similarly to message collectors, except that you apply them on a message rather than a channel. This example uses the <DocsLink type="class" parent="Message" symbol="createReactionCollector" brackets /> method. The filter will check for the 👍 emojiin the default skin tone specifically, so be wary of that. It will also check that the person who reacted shares the same id as the author of the original message that the collector was assigned to.
```js
const collectorFilter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === message.author.id;
};
const collector = message.createReactionCollector({ filter: collectorFilter, time: 15_000 });
collector.on('collect', (reaction, user) => {
console.log(`Collected ${reaction.emoji.name} from ${user.tag}`);
});
collector.on('end', (collected) => {
console.log(`Collected ${collected.size} items`);
});
```
### Await reactions
<DocsLink type="class" parent="Message" symbol="awaitReactions" brackets /> works almost the same as a reaction
collector, except it is Promise-based. The same differences apply as with channel collectors.
```js
const collectorFilter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === message.author.id;
};
try {
const collected = await message.awaitReactions({ filter: collectorFilter, max: 1, time: 60_000, errors: ['time'] });
console.log(collected.size);
} catch (collected) {
console.log(`After a minute, the user did not react.`);
}
```
## Interaction collectors
The third type of collector allows you to collect interactions; such as when users activate a slash command or click on a button in a message.
### Basic message component collector
Collecting interactions from message components works similarly to reaction collectors. In the following example, you will check that the interaction came from a button, and that the user clicking the button is the same user that initiated the command.
One important difference to note with interaction collectors is that Discord expects a response to _all_ interactions within 3 seconds - even ones that you don't want to collect. For this reason, you may wish to _`.deferUpdate()`_ all interactions in your filter, or not use a filter at all and handle this behavior in the _`collect`_ event.
```js
import { ComponentType } from 'discord.js';
const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, time: 15_000 });
collector.on('collect', (i) => {
if (i.user.id === interaction.user.id) {
await i.reply(`${i.user.id} clicked on the ${i.customId} button.`);
} else {
await i.reply({ content: `These buttons aren't for you!`, ephemeral: true });
}
});
collector.on('end', (collected) => {
console.log(`Collected ${collected.size} interactions.`);
});
```
### Await message component
As before, this works similarly to the message component collector, except it is Promise-based.
Unlike other Promise-based collectors, this method will only ever collect one interaction that passes the filter. If no interactions are collected before the time runs out, the Promise will reject. This behavior aligns with Discord's requirement that actions should immediately receive a response. In this example, you will use _`.deferUpdate()`_ on all interactions in the filter.
```js
import { ComponentType } from 'discord.js';
const collectorFilter = (i) => {
i.deferUpdate();
return i.user.id === interaction.user.id;
};
try {
const interaction = await message.awaitMessageComponent({
filter: collectorFilter,
componentType: ComponentType.StringSelect,
time: 60_000,
});
await interaction.editReply(`You selected ${interaction.values.join(', ')}!`);
} catch (error) {
console.log('No interactions were collected.');
}
```
### Await modal submit
If you want to wait for the submission of a modal within the context of another command or button execution, you may find the promisified collector <DocsLink type="class" parent="CommandInteraction" symbol="awaitModalSubmit" brackets /> useful.
As Discord does not inform you if the user dismisses the modal, supplying a maximum _`time`_ to wait for is crucial:
```js
try {
const interaction = await initialInteraction.awaitModalSubmit({ time: 60_000, filter });
await interaction.editReply('Thank you for your submission!');
} catch (error) {
console.log('No modal submit interaction was collected');
}
```
For more information on working with modals, see the [modals section of this guide](../interactions/modals).

View File

@@ -1,95 +0,0 @@
---
title: Formatters
category: Topics
---
# Formatters
discord.js provides the <DocsLink package="formatters" /> package which contains a variety of utilities you can use when writing your Discord bot.
## Basic Markdown
These functions format strings into all the different markdown styles supported by Discord.
<CH.Code>
```js
import { bold, italic, strikethrough, underscore, spoiler, quote, blockQuote } from 'discord.js';
const string = 'Hello!';
const boldString = bold(string);
const italicString = italic(string);
const strikethroughString = strikethrough(string);
const underscoreString = underscore(string);
const spoilerString = spoiler(string);
const quoteString = quote(string);
const blockquoteString = blockQuote(string);
```
</CH.Code>
## Links
There are also two functions to format hyperlinks. _`hyperlink()`_ will format the URL into a masked markdown link, and _`hideLinkEmbed()`_ will wrap the URL in _`<>`_, preventing it from embedding.
<CH.Code>
```js
import { hyperlink, hideLinkEmbed } from 'discord.js';
const url = 'https://discord.js.org/';
const link = hyperlink('discord.js', url);
const hiddenEmbed = hideLinkEmbed(url);
```
</CH.Code>
## Code blocks
You can use _`inlineCode()`_ and _`codeBlock()`_ to turn a string into an inline code block or a regular code block with or without syntax highlighting.
<CH.Code>
```js
import { inlineCode, codeBlock } from 'discord.js';
const jsString = 'const value = true;';
const inline = inlineCode(jsString);
const codeblock = codeBlock(jsString);
const highlighted = codeBlock('js', jsString);
```
</CH.Code>
## Timestamps
With _`time()`_, you can format Unix timestamps and dates into a Discord time string.
<CH.Code>
```js
import { time, TimestampStyles } from 'discord.js';
const date = new Date();
const timeString = time(date);
const relative = time(date, TimestampStyles.RelativeTime);
```
</CH.Code>
## Mentions
_`userMention()`_, _`channelMention()`_, and _`roleMention()`_ all exist to format Snowflakes into mentions.
<CH.Code>
```js
import { channelMention, roleMention, userMention } from 'discord.js';
const id = '123456789012345678';
const channel = channelMention(id);
const role = roleMention(id);
const user = userMention(id);
```
</CH.Code>

View File

@@ -1,68 +0,0 @@
---
title: Intents
category: Topics
---
# Intents
Intents are an important part of establishing a WebSocket connection, as they define behavior regarding gateway events and impact received data via the REST API.
## Usage
```js
import { Client, GatewayIntentBits } from 'discord.js';
const client = new Client({
intents: [GatewayIntentBits.Guilds],
});
```
This is the most basic usage of intents for discord.js. By specifying _`GatewayIntentBits.Guilds`_, your bot will receive gateway events regarding guilds. This includes receiving initial information about guilds it is in at startup, such as role data.
You can find the full list of _`GatewayIntentBits`_ <DiscordAPITypesLink type="enum" parent="GatewayIntentBits">on the documentation</DiscordAPITypesLink> and an explanation of what each intent does [on Discord's API documentation](https://discord.com/developers/docs/topics/gateway#list-of-intents).
## Considerations
In discord.js, some intents require an extra bit of consideration.
### _`GatewayIntentBits.Guilds`_
discord.js relies heavily on caching in the library. We recommend you set at least the _`GatewayIntentBits.Guilds`_ intent to avoid these pitfalls.
### _`GatewayIntentBits.GuildMembers`_
Fetching members in a guild via <DocsLink type="class" parent="GuildMemberManager" symbol="fetch" brackets /> requests them over the gateway. As such, this intent is required and you may receive a timeout error if this intent is not specified.
<Alert title="Info" type="info">
This is a privileged intent. Read on for more information.
</Alert>
### _`GatewayIntentBits.DirectMessages`_
This intent is required to receive direct messages. In discord.js however, you **must** specify partials as well. See the partials topic on how this is done.
### _`GatewayIntentBits.MessageContent`_
Unlike other intents, this only populates user-generated fields. See [Discord's documentation](https://discord.com/developers/docs/topics/gateway#message-content-intent) on what exactly this intent unveils.
It is a common mistake to not see the message content in a message—this is usually because this intent is not specified.
<Alert title="Info" type="info">
This is a privileged intent. Read on for more information.
</Alert>
## Privileged intents
Some gateway events are considered privileged. Currently, these are:
- _`GatewayIntentBits.GuildPresences`_
- _`GatewayIntentBits.GuildMembers`_
- _`GatewayIntentBits.MessageContent`_
To use these intents, you will need to enable them in the developer portal. If your bot is in over 75 guilds, you will need to verify it and request usage of your desired intents.
Carefully think if you need these intents. They are opt-in so users across the platform can enjoy a higher level of privacy. Presences can expose some personal information, such as the games being played and overall online time. You might find that it isn't necessary for your bot to have this level of information about all guild members at all times.
### Disallowed intents
Should you receive an error stating you are using disallowed intents, please review your developer dashboard settings for all privileged intents you use. Check the Discord API documentation for up-to-date information.

View File

@@ -1,202 +0,0 @@
---
title: Threads
category: Topics
---
# Threads
Threads can be thought of as temporary sub-channels inside an existing channel to help better organize conversations in a busy channel.
## Thread related gateway events
<Alert title="Tip" type="info">
You can use the <DocsLink type="class" parent="BaseChannel" symbol="isThread" brackets /> type guard to make sure a
channel is a <DocsLink type="class" parent="ThreadChannel" />!
</Alert>
Threads introduce a number of new gateway events, which are listed below:
- <DocsLink type="class" parent="Client" symbol="e-threadCreate" />: Emitted whenever a thread is created or when the
client user is added to a thread.
- <DocsLink type="class" parent="Client" symbol="e-threadDelete" />: Emitted whenever a thread is deleted.
- <DocsLink type="class" parent="Client" symbol="e-threadUpdate" />: Emitted whenever a thread is updated (e.g. name
change, archive state change, locked state change).
- <DocsLink type="class" parent="Client" symbol="e-threadListSync" />: Emitted whenever the client user gains access to
a text or announcement channel that contains threads.
- <DocsLink type="class" parent="Client" symbol="e-threadMembersUpdate" />: Emitted whenever members are added or
removed from a thread. Requires <code>GuildMembers</code> privileged intent.
- <DocsLink type="class" parent="Client" symbol="e-threadMemberUpdate" />: Emitted whenever the client user's thread
member is updated.
## Creating and deleting threads
Threads are created and deleted using the <DocsLink type="class" parent="GuildTextThreadManager" /> of a text or announcement channel.
To create a thread, you call the <DocsLink type="class" parent="GuildTextThreadManager" symbol="create" brackets /> method:
<CH.Code>
```js
import { ThreadAutoArchiveDuration } from 'discord.js';
const thread = await channel.threads.create({
name: 'food-talk',
autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
reason: 'Needed a separate thread for food',
});
console.log(`Created thread: ${thread.name}`);
```
</CH.Code>
They can also be created from an existing message with the <DocsLink type="class" parent="Message" symbol="startThread" brackets /> method, but will be "orphaned" if that message is deleted.
<CH.Code>
```js focus=3[22:42]
import { ThreadAutoArchiveDuration } from 'discord.js';
const thread = await message.startThread({
name: 'food-talk',
autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
reason: 'Needed a separate thread for food',
});
console.log(`Created thread: ${thread.name}`);
```
</CH.Code>
The created thread and the message it originated from will share the same id. The type of thread created matches the parent channel's type.
To delete a thread, use the <DocsLink type="class" parent="ThreadChannel" symbol="delete" brackets /> method:
<CH.Code>
```js focus=2
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
if (thread.manageable) await thread.delete();
```
</CH.Code>
## Joining and leaving threads
To subscribe your client to a thread, use the <DocsLink type="class" parent="ThreadChannel" symbol="join" brackets /> method:
<CH.Code>
```js focus=2
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
if (thread.joinable) await thread.join();
```
</CH.Code>
And to leave one, use the <DocsLink type="class" parent="ThreadChannel" symbol="leave" brackets /> method:
<CH.Code>
```js focus=2
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
await thread.leave();
```
</CH.Code>
## Archiving, unarchiving, and locking threads
A thread can be either active or archived. Changing a thread from archived to active is referred to as unarchiving the thread. Threads that have _`locked`_ set to _`true`_ can only be unarchived by a member with the _`ManageThreads`_ permission.
Threads are automatically archived after inactivity. "Activity" is defined as sending a message, unarchiving a thread, or changing the auto-archive time.
To archive or unarchive a thread, use the <DocsLink type="class" parent="ThreadChannel" symbol="setArchived" brackets /> method and pass in a boolean parameter:
<CH.Code>
```js focus=2,3
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
await thread.setArchived(true); // Archived.
await thread.setArchived(false); // Unarchived.
```
</CH.Code>
This same principle applies to locking and unlocking a thread via the <DocsLink type="class" parent="ThreadChannel" symbol="setLocked" brackets /> method:
<CH.Code>
```js focus=2,3
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
await thread.setLocked(true); // Locked.
await thread.setLocked(false); // Unlocked.
```
</CH.Code>
## Private threads
Public threads are viewable by everyone who can view the parent channel of the thread. Private threads, however, are only viewable to those who are invited or have the _`ManageThreads`_ permission. Private threads can only be created on text channels.
To create a private thread, use the <DocsLink type="class" parent="GuildTextThreadManager" symbol="create" brackets /> method and pass in _`ChannelType.PrivateThread`_ as the _`type`_:
<CH.Code>
```js focus=1[10:21],6
import { ChannelType, ThreadAutoArchiveDuration } from 'discord.js';
const thread = await channel.threads.create({
name: 'mod-talk',
autoArchiveDuration: ThreadAutoArchiveDuration.OneHour,
type: ChannelType.PrivateThread,
reason: 'Needed a separate thread for moderation',
});
console.log(`Created thread: ${thread.name}`);
```
</CH.Code>
## Adding and removing members
You can add members to a thread with the <DocsLink type="class" parent="ThreadMemberManager" symbol="add" brackets /> method. The thread must be unarchived and you must be able to send messages in it.
<CH.Code>
```js focus=2
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
await thread.members.add('12345678901234567');
```
</CH.Code>
You can remove members from a thread with the <DocsLink type="class" parent="ThreadMemberManager" symbol="remove" brackets /> method. The thread must be unarchived and you must have the _`ManageThreads`_ permission unless the thread is private and you are the owner of it.
<CH.Code>
```js focus=2
const thread = channel.threads.cache.find((x) => x.name === 'food-talk');
await thread.members.remove('12345678901234567');
```
</CH.Code>
## Sending messages to threads with webhooks
It is possible for a webhook built on the parent channel to send messages to the channel's threads. For the purpose of this example, it is assumed a single webhook already exists for that channel. If you wish to learn more about webhooks, see our [webhook guide](./webhooks).
<CH.Code>
```js focus=4:7
const webhooks = await channel.fetchWebhooks();
const webhook = webhooks.first();
await webhook.send({
content: "Look ma! I'm in a thread!",
threadId: '123456789012345678',
});
```
</CH.Code>
And that's it! Now you know all there is to know on working with threads using discord.js!

View File

@@ -1,227 +0,0 @@
---
title: Webhooks
category: Topics
---
# Webhooks
Webhooks can send messages to a text channel without having to log in as a bot. They can also fetch, edit, and delete their own messages. There are a variety of methods in discord.js to interact with webhooks. In this section, you will learn how to create, fetch, edit, and use webhooks.
## What is a webhook
Webhooks are a utility used to send messages to text channels without needing a Discord application. Webhooks are useful for allowing something to send messages without requiring a Discord application. You can also directly edit or delete messages you sent through the webhook. There are two structures to make use of this functionality: <DocsLink type="class" parent="Webhook" /> and <DocsLink type="class" parent="WebhookClient" />. _`WebhookClient`_ is an extended version of a _`Webhook`_, which allows you to send messages through it without needing a bot client.
<Alert title="Tip" type="info">
If you would like to read about using webhooks through the API without discord.js, you can read about them
[here](https://discord.com/developers/docs/resources/webhook).
</Alert>
## Detecting webhook messages
Bots receive webhook messages in a text channel as usual. You can detect if a webhook sent the message by checking if the _`Message.webhookId`_ is not _`null`_. In this example, we return if a webhook sent the message.
<CH.Code>
```js
if (message.webhookId) return;
```
</CH.Code>
If you would like to get the webhook object that sent the message, you can use <DocsLink type="class" parent="Message" symbol="fetchWebhook" brackets />.
## Fetching webhooks
<Alert title="Tip" type="info">
Webhook fetching will always make use of collections and promises. If you do not understand either concept, revise
them, and then come back to this section. You can read about collections [here](../additional-info/collections), and
promises [here](../additional-info/understanding-async-await) and
[here](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Using_promises).
</Alert>
### Fetching all webhooks of a guild
If you would like to get all webhooks of a guild, you can use the <DocsLink type="class" parent="Guild" symbol="fetchWebhooks" brackets /> method. This will return a promise which will resolve into a collection of webhooks.
### Fetching webhooks of a channel
Webhooks belonging to a channel can be fetched using the <DocsLink type="class" parent="TextChannel" symbol="fetchWebhooks" brackets /> method. This will return a promise which will resolve into a collection of webhooks. A collection will be returned even if the channel contains a single webhook. If you are certain the channel contains a single webhook, you can use the <DocsLink package="collection" type="Class" parent="Collection" symbol="first" brackets /> method on the collection to get the webhook.
### Fetching a single webhook
#### Using client
You can fetch a specific webhook using its _`id`_ with the <DocsLink type="class" parent="Client" symbol="fetchWebhook" brackets /> method. You can obtain the webhook id by looking at its URL: the number after _`https://discord.com/api/webhooks/`_ is the _`id`_ and the part after that is the _`token`_.
#### Using the WebhookClient constructor
If you are not using a bot client, you can get a webhook by creating a new instance of _`WebhookClient`_ and passing the _`id`_ and _`token`_ into the constructor. These credentials do not require you to have a bot application, but it also offers limited information instead of fetching it using an authorized client.
<CH.Code>
```js
const webhookClient = new WebhookClient({ id: 'id', token: 'token' });
```
</CH.Code>
You can also pass in just a _`url`_:
<CH.Code>
```js
const webhookClient = new WebhookClient({ url: 'https://discord.com/api/webhooks/id/token' });
```
</CH.Code>
## Creating webhooks
### Creating webhooks through server settings
You can create webhooks directly through the Discord client. Go to Server Settings, and you will see an _`Integrations`_ tab.
![Integrations tab](/assets/integrations-tab.png)
If you already have created a webhook, the webhooks tab will look like this; you will need to click the _`View Webhooks`_ button.
![Integrations tab](/assets/integrations-view-tab.png)
Once you are there, click on the _`Create Webhook`_ / _`New Webhook`_ button; this will create a webhook. From here, you can edit the channel, the name, and the avatar. Copy the link, the first part is the id, and the second is the token.
![Creating a Webhook](/assets/webhook.png)
### Creating webhooks with discord.js
Webhooks can be created with the <DocsLink type="class" parent="TextChannel" symbol="createWebhook" brackets /> method.
<CH.Code>
```js
channel
.createWebhook({ name: 'Username', avatar: 'https://guide.discordjs.dev/assets/discordjs.png' })
.then((webhook) => console.log(`Created webhook ${webhook}`))
.catch(console.error);
```
</CH.Code>
## Editing webhooks
You can edit Webhooks and WebhookClients to change their name, avatar, and channel using <DocsLink type="class" parent="Webhook" symbol="edit" brackets />.
<CH.Code>
```js
webhook
.edit({ name: 'Username', avatar: 'https://guide.discordjs.dev/assets/discordjs.png', channel: '123456789012345678' })
.then((webhook) => console.log(`Edited webhook ${webhook}`))
.catch(console.error);
```
</CH.Code>
## Using webhooks
Webhooks can send messages to text channels, as well as fetch, edit, and delete their own. These methods are the same for both _`Webhook`_ and _`WebhookClient`_.
### Sending messages
Webhooks, like bots, can send up to 10 embeds per message. They can also send attachments and normal content. The <DocsLink type="class" parent="Webhook" symbol="send" brackets /> method is very similar to the method used for sending a message to a text channel. Webhooks can also choose how the username and avatar will appear when they send the message.
Example using a _`WebhookClient`_:
<CH.Code>
```js
import { EmbedBuilder, WebhookClient } from 'discord.js';
import config from './config.json' assert { type: 'json' };
const { webhookId, webhookToken } = config;
const webhookClient = new WebhookClient({ id: webhookId, token: webhookToken });
const embed = new EmbedBuilder().setTitle('Some Title').setColor(0x00ffff);
await webhookClient.send({
content: 'Webhook test',
username: 'some-username',
avatarURL: 'https://guide.discordjs.dev/assets/discordjs.png',
embeds: [embed],
});
```
</CH.Code>
Try to find a webhook your bot knows the token for. This makes sure your bot can execute the webhook later on.
<CH.Code>
```js
import { Client, EmbedBuilder, Events, GatewayIntentBits } from 'discord.js';
import config from './config.json' assert { type: 'json' };
const { token } = config;
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const embed = new EmbedBuilder().setTitle('Some Title').setColor(0x00ffff);
client.once(Events.ClientReady, async () => {
const channel = client.channels.cache.get('123456789012345678');
try {
const webhooks = await channel.fetchWebhooks();
const webhook = webhooks.find((wh) => wh.token);
if (!webhook) return console.log('No webhook was found that I can use!');
await webhook.send({
content: 'Webhook test',
username: 'some-username',
avatarURL: 'https://guide.discordjs.dev/assets/discordjs.png',
embeds: [embed],
});
} catch (error) {
console.error('Error trying to send a message: ', error);
}
});
client.login(token);
```
</CH.Code>
### Fetching messages
You can use <DocsLink type="class" parent="Webhook" symbol="fetchMessage" brackets /> to fetch messages previously sent by the Webhook.
<CH.Code>
```js
const message = await webhookClient.fetchMessage('123456789012345678');
```
</CH.Code>
### Editing messages
You can use <DocsLink type="class" parent="Webhook" symbol="editMessage" brackets /> to edit messages previously sent by the Webhook.
<CH.Code>
```js
const message = await webhook.editMessage('123456789012345678', {
content: 'Edited!',
embeds: [embed],
});
```
</CH.Code>
### Deleting messages
You can use <DocsLink type="class" parent="Webhook" symbol="deleteMessage" brackets /> to delete messages previously sent by the webhook.
<CH.Code>
```js
await webhookClient.deleteMessage('123456789012345678');
```
</CH.Code>

View File

@@ -1,249 +0,0 @@
---
title: Understanding async/await
category: Additional info
---
# Understanding async/await
If you aren't very familiar with ECMAScript 2017, you may not know about async/await. It's a useful way to handle Promises in a hoisted manner. It's also slightly faster and increases overall readability.
## How do Promises work?
Before we can get into async/await, you should know what Promises are and how they work because async/await is just a way to handle Promises. If you know what Promises are and how to deal with them, you can skip this part.
Promises are a way to handle asynchronous tasks in JavaScript; they are the newer alternative to callbacks. A Promise has many similarities to a progress bar; they represent an unfinished and ongoing process. An excellent example of this is a request to a server (e.g., discord.js sends requests to Discord's API).
A Promise can have three states; pending, resolved, and rejected
The **pending** state means that the Promise still is ongoing and neither resolved nor rejected.
The **resolved** state means that the Promise is done and executed without any errors.
The **rejected** state means that the Promise encountered an error and could not execute correctly.
One important thing to know is that a Promise can only have one state simultaneously; it can never be pending and resolved, rejected and resolved, or pending and rejected. You may be asking, "How would that look in code?". Here is a small example:
<Alert title="Tip" type="success">
This example uses ES6 code. If you do not know what that is, you should read up on that
[here](/additional-info/es6-syntax.md).
</Alert>
<CH.Code>
```js
function deleteMessages(amount) {
return new Promise((resolve) => {
if (amount > 10) throw new Error("You can't delete more than 10 Messages at a time.");
setTimeout(() => resolve('Deleted 10 messages.'), 2000);
});
}
deleteMessages(5)
.then((value) => {
// `deleteMessages` is complete and has not encountered any errors
// the resolved value will be the string "Deleted 10 messages"
})
.catch((error) => {
// `deleteMessages` encountered an error
// the error will be an Error Object
});
```
</CH.Code>
In this scenario, the _`deleteMessages`_ function returns a Promise. The _`.then()`_ method will trigger if the Promise resolves, and the _`.catch()`_ method if the Promise rejects. In the _`deleteMessages`_ function, the Promise is resolved after 2 seconds with the string "Deleted 10 messages.", so the _`.catch()`_ method will never be executed. You can also pass the _`.catch()`_ function as the second parameter of _`.then()`_.
## How to implement async/await
### Theory
The following information is essential to know before working with async/await. You can only use the _`await`_ keyword inside a function declared as _`async`_ (you put the _`async`_ keyword before the _`function`_ keyword or before the parameters when using a callback function).
A simple example would be:
<CH.Code>
```js
async function declaredAsAsync() {
// ...
}
```
</CH.Code>
or
<CH.Code>
```js
const declaredAsAsync = async () => {
// ...
};
```
</CH.Code>
You can use that as well if you use the arrow function as an event listener.
<CH.Code>
```js
client.on('event', async (first, last) => {
// ...
});
```
</CH.Code>
An important thing to know is that a function declared as _`async`_ will always return a Promise. In addition to this, if you return something, the Promise will resolve with that value, and if you throw an error, it will reject the Promise with that error.
### Execution with discord.js code
Now that you know how Promises work and what they are used for, let's look at an example that handles multiple Promises. Let's say you want to react with letters (regional indicators) in a specific order. For this example, here's a basic template for a discord.js bot with some ES6 adjustments.
<CH.Code>
```js
import { Client, Events, GatewayIntentBits } from 'discord.js';
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.once(Events.ClientReady, () => {
console.log('I am ready!');
});
client.on(Events.InteractionCreate, (interaction) => {
if (!interaction.isChatInputCommand()) return;
if (interaction.commandName === 'react') {
// ...
}
});
client.login('your-token-goes-here');
```
</CH.Code>
If you don't know how Node.js asynchronous execution works, you would probably try something like this:
<CH.Code>
```js mark=4:7
client.on('interactionCreate', (interaction) => {
// ...
if (commandName === 'react') {
const message = interaction.reply({ content: 'Reacting!', fetchReply: true });
message.react('🇦');
message.react('🇧');
message.react('🇨');
}
});
```
</CH.Code>
But since all of these methods are started at the same time, it would just be a race to which server request finished first, so there would be no guarantee that it would react at all (if the message isn't fetched) or in the order you wanted it to. In order to make sure it reacts after the message is sent and in order (a, b, c), you'd need to use the _`.then()`_ callback from the Promises that these methods return. The code would look like this:
<CH.Code>
```js mark=4:12
client.on('interactionCreate', (interaction) => {
// ...
if (commandName === 'react') {
interaction.reply({ content: 'Reacting!', fetchReply: true }).then((message) => {
message
.react('🇦')
.then(() => message.react('🇧'))
.then(() => message.react('🇨'))
.catch((error) => {
// handle failure of any Promise rejection inside here
});
});
}
});
```
</CH.Code>
In this piece of code, the Promises are [chain resolved](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Chaining) with each other, and if one of the Promises gets rejected, the function passed to _`.catch()`_ gets called. Here's the same code but with async/await:
<CH.Code>
```js mark=1,4:7
client.on('interactionCreate', async (interaction) => {
// ...
if (commandName === 'react') {
const message = await interaction.reply({ content: 'Reacting!', fetchReply: true });
await message.react('🇦');
await message.react('🇧');
await message.react('🇨');
}
});
```
</CH.Code>
It's mostly the same code, but how would you catch Promise rejections now since _`.catch()`_ isn't there anymore? That is also a useful feature with async/await; the error will be thrown if you await it so that you can wrap the awaited Promises inside a try/catch, and you're good to go.
<CH.Code>
```js mark=1,4:11
client.on('interactionCreate', async (interaction) => {
if (commandName === 'react') {
try {
const message = await interaction.reply({ content: 'Reacting!', fetchReply: true });
await message.react('🇦');
await message.react('🇧');
await message.react('🇨');
} catch (error) {
// handle failure of any Promise rejection inside here
}
}
});
```
</CH.Code>
This code looks clean and is also easy to read.
So you may be asking, "How would I get the value the Promise resolved with?".
Let's look at an example where you want to delete a sent reply.
<CH.Code>
```js mark=3:10
client.on('interactionCreate', (interaction) => {
// ...
if (commandName === 'delete') {
interaction
.reply({ content: 'This message will be deleted.', fetchReply: true })
.then((replyMessage) => setTimeout(() => replyMessage.delete(), 10000))
.catch((error) => {
// handle error
});
}
});
```
</CH.Code>
The return value of a _`.reply()`_ with the _`fetchReply`_ option set to _`true`_ is a Promise which resolves with the reply when it has been sent, but how would the same code with async/await look?
<CH.Code>
```js mark=1,4:10
client.on('interactionCreate', async (interaction) => {
if (commandName === 'delete') {
try {
const replyMessage = await interaction.reply({ content: 'This message will be deleted.', fetchReply: true });
setTimeout(() => replyMessage.delete(), 10000);
} catch (error) {
// handle error
}
}
});
```
</CH.Code>
With async/await, you can assign the awaited function to a variable representing the returned value. Now you know how you use async/await.

View File

@@ -1,123 +0,0 @@
---
title: Collections
category: Additional info
---
# Collections
discord.js comes with a utility class known as _`Collection`_.
It extends JavaScript's native _`Map`_ class, so it has all the _`Map`_ features and more!
<Alert title="Warning" type="warning">
If you're not familiar with _`Map`_, read [MDN's page on
it](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map) before continuing. You should be
familiar with _`Array`_ [methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array) as
well. We will also use some ES6 features, so read up [here](/additional-info/es6-syntax.md) if you do not know what
they are.
</Alert>
A _`Map`_ allows for an association between unique keys and their values.
For example, how can you transform every value or filter the entries in a _`Map`_ easily?
This is the point of the _`Collection`_ class!
## Array-like Methods
Many of the methods on _`Collection`_ correspond to their namesake in _`Array`_. One of them is _`find`_:
<CH.Code>
```js
// Assume we have an array of users and a collection of the same users.
array.find((u) => u.discriminator === '1000');
collection.find((u) => u.discriminator === '1000');
```
</CH.Code>
The interface of the callback function is very similar between the two.
For arrays, callbacks usually pass the parameters _`(value, index, array)`_, where _`value`_ is the value iterated to,
_`index`_ is the current index, and _`array`_ is the array. For collections, you would have _`(value, key, collection)`_.
Here, _`value`_ is the same, but _`key`_ is the key of the value, and _`collection`_ is the collection itself instead.
Methods that follow this philosophy of staying close to the _`Array`_ interface are as follows:
- _`find`_
- _`filter`_ - Note that this returns a _`Collection`_ rather than an _`Array`_.
- _`map`_ - Yet this returns an _`Array`_ of values instead of a _`Collection`_!
- _`every`_
- _`some`_
- _`reduce`_
- _`concat`_
- _`sort`_
## Converting to Array
Since _`Collection`_ extends _`Map`_, it is an [iterable](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Iteration_protocols), and can be converted to an _`Array`_ through either _`Array.from()`_ or spread syntax (_`...collection`_).
<CH.Code>
```js
// For values.
Array.from(collection.values());
[...collection.values()];
// For keys.
Array.from(collection.keys());
[...collection.keys()];
// For [key, value] pairs.
Array.from(collection);
[...collection];
```
</CH.Code>
<Alert title="Warning" type="warning">
Many people convert Collections to Arrays way too much! This can lead to unnecessary and confusing code. Before you
use _`Array.from()`_ or similar, ask yourself if whatever you are trying to do can't be done with the given _`Map`_ or
_`Collection`_ methods or with a for-of loop.
</Alert>
## Extra Utilities
Some methods are not from _`Array`_ and are instead entirely new to standard JavaScript.
<CH.Code>
```js
// A random value.
collection.random();
// The first value.
collection.first();
// The first 5 values.
collection.first(5);
// Similar to `first`, but from the end.
collection.last();
collection.last(2);
// Removes anything that meets the condition from the collection.
// Sort of like `filter`, but in-place.
collection.sweep((user) => user.username === 'Bob');
```
</CH.Code>
A more complicated method is _`partition`_, which splits a single Collection into two new Collections based on the provided function.
You can think of it as two \_`filter`\_ methods, but done at the same time:
<CH.Code>
```js
// `bots` is a Collection of users where their `bot` property was true.
// `humans` is a Collection where the property was false instead!
const [bots, humans] = collection.partition((u) => u.bot);
// Both return true.
bots.every((b) => b.bot);
humans.every((h) => !h.bot);
```
</CH.Code>

View File

@@ -1,834 +0,0 @@
---
title: Updating to v14
category: Additional info
---
# Updating to v14
## Before you start
v14 requires Node 16.11 or higher to use, so make sure you're up to date. To check your Node.js version, use _`node --version`_ in your terminal or command prompt, and if it's not high enough, update it! There are many resources online to help you with this step based on your host system.
### Various packages are now included in v14
If you previously had _`@discordjs/builders`_, _`@discordjs/formatters`_, _`@discordjs/rest`_, or _`discord-api-types`_ manually installed, it's _highly_ recommended that you uninstall the packages to avoid package version conflicts.
<CH.Code>
```sh npm
npm uninstall @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```
```sh yarn
yarn remove @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```
```sh pnpm
pnpm remove @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```
```sh bun
bun remove @discordjs/builders @discordjs/formatters @discordjs/rest discord-api-types
```
</CH.Code>
## Breaking Changes
### API version
discord.js v14 makes the switch to Discord API v10!
### Common Breakages
### Enum Values
Any areas that used to accept a _`string`_ or _`number`_ type for an enum parameter will now only accept a _`number`_.
In addition, the old enums exported by discord.js v13 and lower are replaced with new enums from <DiscordAPITypesLink />.
#### New enum differences
Most of the difference between enums from discord.js and discord-api-types can be summarized as so:
1. Enums are singular, i.e., _`ApplicationCommandOptionTypes`_ -> _`ApplicationCommandOptionType`_
2. Enums that are prefixed with _`Message`_ no longer have the _`Message`_ prefix, i.e., _`MessageButtonStyles`_ -> _`ButtonStyle`_
3. Enum values are _`PascalCase`_ rather than `SCREAMING_SNAKE_CASE`, i.e., `.CHAT_INPUT` -> `.ChatInput`
<Alert title="Magic Numbers Warning" type="danger">
You might be inclined to a raw _`number`_ (most commonly referred to as [magic
numbers](https://en.wikipedia.org/wiki/Magic_number_(programming))) instead of enum values. This is highly
discouraged. Enums provide more readability and are more resistant to changes in the API. Magic numbers can obscure
the meaning of your code in many ways. Check out this [blog
post](https://blog.webdevsimplified.com/2020-02/magic-numbers) if you want more context on as to why they shouldn't be
used.
</Alert>
#### Common enum breakages
Areas like _`Client`_ initialization, JSON slash commands and JSON message components will likely need to be modified to accommodate these changes:
##### Common Client Initialization Changes
<CH.Code>
```diff
- import { Client, Intents } = from 'discord.js';
+ import { Client, GatewayIntentBits, Partials } = from 'discord.js';
- const client = new Client({ intents: [Intents.FLAGS.GUILDS], partials: ['CHANNEL'] });
+ const client = new Client({ intents: [GatewayIntentBits.Guilds], partials: [Partials.Channel] });
```
</CH.Code>
##### Common Application Command Data changes
<CH.Code>
```diff
+ import { ApplicationCommandType, ApplicationCommandOptionType } = from 'discord.js';
const command = {
name: 'ping',
- type: 'CHAT_INPUT',
+ type: ApplicationCommandType.ChatInput,
options: [{
name: 'option',
description: 'A sample option',
- type: 'STRING',
+ type: ApplicationCommandOptionType.String,
}],
};
```
</CH.Code>
##### Common Button Data changes
<CH.Code>
```diff
+ import { ButtonStyle } = from 'discord.js';
const button = {
label: 'test',
- style: 'PRIMARY',
+ style: ButtonStyle.Primary,
customId: '1234'
}
```
</CH.Code>
### Removal of method-based type guards
#### Channels
Some channel type guard methods that narrowed to one channel type have been removed. Instead compare the _`type`_ property against a <DiscordAPITypesLink type="enum" parent="ChannelType" /> enum member to narrow channels.
<CH.Code>
```diff
- channel.isText();
+ channel.type === ChannelType.GuildText;
- channel.isVoice();
+ channel.type === ChannelType.GuildVoice;
- channel.isDM();
+ channel.type === ChannelType.DM;
```
</CH.Code>
### Builders
Builders are no longer returned by the API like they were previously. For example, you send the API an <DocsLink type="class" parent="EmbedBuilder"/> but you receive an <DocsLink type="class" parent="Embed"/> of the same data. This may affect how your code handles received structures such as components. Refer to [message component changes section](#messagecomponent) for more details.
Added <DocsLink package="builders" type="Function" parent="disableValidators" /> and <DocsLink package="builders" type="Function" parent="enableValidators" /> as top-level exports which disable or enable validation (enabled by default).
### Consolidation of create & edit parameters
Various _`create()`_ and _`edit()`_ methods on managers and objects have had their parameters consolidated. The changes are below:
- <DocsLink type="class" parent="Guild" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="GuildChannel" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="GuildEmoji" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="Role" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="Sticker" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="ThreadChannel" symbol="edit" brackets /> now takes _`reason`_ in the _`data`_ parameter
- <DocsLink type="class" parent="GuildChannelManager" symbol="create" brackets /> now takes _`name`_ in the _`options`_
parameter
- <DocsLink type="class" parent="GuildChannelManager" symbol="createWebhook" brackets /> (and other text-based channels)
now takes _`channel`_ and _`name`_ in the _`options`_ parameter
- <DocsLink type="class" parent="GuildChannelManager" symbol="edit" brackets /> now takes _`reason`_ as a part of
_`data`_
- <DocsLink type="class" parent="GuildEmojiManager" symbol="edit" brackets /> now takes _`reason`_ as a part of _`data`_
- <DocsLink type="class" parent="GuildManager" symbol="create" brackets /> now takes _`name`_ as a part of _`options`_
- <DocsLink type="class" parent="GuildMemberManager" symbol="edit" brackets /> now takes _`reason`_ as a part of
_`data`_
- <DocsLink type="class" parent="GuildMember" symbol="edit" brackets /> now takes _`reason`_ as a part of _`data`_
- <DocsLink type="class" parent="GuildStickerManager" symbol="edit" brackets /> now takes _`reason`_ as a part of
_`data`_
- <DocsLink type="class" parent="RoleManager" symbol="edit" brackets /> now takes _`reason`_ as a part of _`options`_
- <DocsLink type="class" parent="Webhook" symbol="edit" brackets /> now takes _`reason`_ as a part of _`options`_
- <DocsLink type="class" parent="GuildEmojiManager" symbol="create" brackets /> now takes _`attachment`_ and _`name`_ as
a part of _`options`_
- <DocsLink type="class" parent="GuildStickerManager" symbol="create" brackets /> now takes _`file`_, _`name`_, and
_`tags`_ as a part of _`options`_
### Activity
The following properties have been removed as they are not supported by the API:
- _`Activity#id`_
- _`Activity#platform`_
- _`Activity#sessionId`_
- _`Activity#syncId`_
### Application
_`Application#fetchAssets()`_ has been removed as it is no longer supported by the API.
### BitField
- BitField constituents now have a _`BitField`_ suffix to avoid naming conflicts with the enum names:
```diff
- new Permissions();
+ new PermissionsBitField();
- new MessageFlags();
+ new MessageFlagsBitField();
- new ThreadMemberFlags();
+ new ThreadMemberFlagsBitField();
- new UserFlags();
+ new UserFlagsBitField();
- new SystemChannelFlags();
+ new SystemChannelFlagsBitField();
- new ApplicationFlags();
+ new ApplicationFlagsBitField();
- new Intents();
+ new IntentsBitField();
- new ActivityFlags();
+ new ActivityFlagsBitField();
```
- _`#FLAGS`_ has been renamed to _`#Flags`_
### CDN
The methods that return CDN URLs have changed. Here is an example on a `User`:
<CH.Code>
```diff
- const url = user.displayAvatarURL({ dynamic: true, format: "png", size: 1024 });
+ const url = user.displayAvatarURL({ extension: "png", size: 1024 });
```
</CH.Code>
Dynamic URLs use <DocsLink package="rest" type="Interface" parent="ImageURLOptions"/> and static URLs use <DocsLink package="rest" type="Interface" parent="BaseImageURLOptions"/>. Since dynamic URLs are returned by default, this option has been renamed to _`forceStatic`_ which forces the return of a static URL. Additionally, _`format`_ has been renamed to _`extension`_.
### CategoryChannel
<DocsLink type="class" parent="CategoryChannel" symbol="children" /> is no longer a _`Collection`_ of channels the
category contains. It is now a <DocsLink type="class" parent="CategoryChannelChildManager" />. This also means
_`CategoryChannel#createChannel()`_ has been moved to the <DocsLink type="class" parent="CategoryChannelChildManager" />
.
### Channel
The following type guards have been removed:
- _`Channel#isText()`_
- _`Channel#isVoice()`_
- _`Channel#isDirectory()`_
- _`Channel#isDM()`_
- _`Channel#isGroupDM()`_
- _`Channel#isCategory()`_
- _`Channel#isNews()`_
Refer to [this section](#channels) for more context.
The base channel class is now <DocsLink type="class" parent="BaseChannel"/>.
### Client
The _`restWsBridgeTimeout`_ client option has been removed.
### CommandInteractionOptionResolver
<DocsLink type="class" parent="CommandInteractionOptionResolver" symbol="getMember" brackets /> no longer has a
parameter for _`required`_.[^1]
### Constants
- Many constant objects and key arrays are now top-level exports. For example:
<CH.Code>
```diff
- import { Constants } = from 'discord.js';
- const { Colors } = Constants;
+ import { Colors } = from 'discord.js';
```
</CH.Code>
- The refactored constants structures have _`PascalCase`_ member names as opposed to _`SCREAMING_SNAKE_CASE`_ member names.
- Many of the exported constants structures have been replaced and renamed:
<CH.Code>
```diff
- Opcodes
+ GatewayOpcodes
- WSEvents
+ GatewayDispatchEvents
- WSCodes
+ GatewayCloseCodes
- InviteScopes
+ OAuth2Scopes
```
</CH.Code>
### Events
The _`message`_ and _`interaction`_ events are now removed. Use <DocsLink type="class" parent="Client" symbol="e-messageCreate"/> and <DocsLink type="class" parent="Client" symbol="e-interactionCreate"/> instead.
_`Client#applicationCommandCreate`_, _`Client#applicationCommandDelete`_, and _`Client#applicationCommandUpdate`_ have all been removed.[^2]
The <DocsLink type="class" parent="Client" symbol="e-threadMembersUpdate"/> event now emits the users that were added, the users that were removed, and the thread respectively.
### GuildBanManager
Developers should utilise _`deleteMessageSeconds`_ instead of _`days`_ and _`deleteMessageDays`_:
<CH.Code>
```diff
<GuildBanManager>.create('123456789', {
- days: 3
- deleteMessageDays: 3
+ deleteMessageSeconds: 3 * 24 * 60 * 60
});
```
</CH.Code>
_`deleteMessageDays`_ and _`days`_ are both deprecated and will be removed in the future.
### Guild
<DocsLink type="class" parent="Guild" symbol="setRolePositions" brackets /> and <DocsLink
type="class"
parent="Guild"
symbol="setChannelPositions"
brackets
/> have been removed. Use <DocsLink type="class" parent="RoleManager" symbol="setPositions" brackets /> and <DocsLink
type="class"
parent="GuildChannelManager"
symbol="setPositions"
brackets
/> instead respectively.
<DocsLink type="class" parent="Guild" symbol="maximumPresences" /> no longer has a default value of 25,000.
_`Guild#me`_ has been moved to <DocsLink type="class" parent="GuildMemberManager" symbol="me" />.[^3]
### GuildAuditLogs & GuildAuditLogsEntry
_`GuildAuditLogs.build()`_ has been removed as it has been deemed defunct. There is no alternative.
The following properties & methods have been moved to the <DocsLink type="class" parent="GuildAuditLogsEntry" /> class:
- `GuildAuditLogs.Targets`
- `GuildAuditLogs.actionType()`
- `GuildAuditLogs.targetType()`
### GuildMember
<DocsLink type="class" parent="GuildMember" symbol="pending" /> is now nullable to account for partial guild
members.[^4]
### IntegrationApplication
_`IntegrationApplication#summary`_ has been removed as it is no longer supported by the API.
### Interaction
Whenever an interaction is replied to and one fetches the reply, it could possibly give an <DiscordAPITypesLink type="interface" parent="APIMessage" /> if the guild was not cached. However, interaction replies now always return a discord.js <DocsLink type="class" parent="Message"/> object with _`fetchReply`_ as _`true`_.
The base interaction class is now <DocsLink type="class" parent="BaseInteraction"/>.
### Invite
<DocsLink type="class" parent="Invite" symbol="inviter" /> is now a getter and resolves structures from the cache.
### MessageAttachment
- _`MessageAttachment`_ has now been renamed to <DocsLink type="class" parent="AttachmentBuilder" />.
<CH.Code>
```diff
- new MessageAttachment(buffer, 'image.png');
+ new AttachmentBuilder(buffer, { name: 'image.png' });
```
</CH.Code>
### MessageComponent
- MessageComponents have been renamed as well. They no longer have the _`Message`_ prefix, and now have a _`Builder`_ suffix:
<CH.Code>
```diff
- const button = new MessageButton();
+ const button = new ButtonBuilder();
- const selectMenu = new MessageSelectMenu();
+ const selectMenu = new StringSelectMenuBuilder();
- const actionRow = new MessageActionRow();
+ const actionRow = new ActionRowBuilder();
- const textInput = new TextInputComponent();
+ const textInput = new TextInputBuilder();
```
</CH.Code>
- Components received from the API are no longer directly mutable. If you wish to mutate a component from the API, use _`ComponentBuilder#from()`_. For example, if you want to make a button mutable:
<CH.Code>
```diff
- const editedButton = receivedButton.setDisabled(true);
+ import { ButtonBuilder } = from 'discord.js';
+ const editedButton = ButtonBuilder.from(receivedButton).setDisabled(true);
```
</CH.Code>
### MessageManager
The second parameter of <DocsLink type="class" parent="MessageManager" symbol="fetch" brackets /> has been removed. The <DocsLink type="typedef" parent="BaseFetchOptions" /> the second parameter once was is now merged into the first parameter.
<CH.Code>
```diff
- messageManager.fetch('1234567890', { cache: false, force: true });
+ messageManager.fetch({ message: '1234567890', cache: false, force: true });
```
</CH.Code>
### MessageSelectMenu
- _`MessageSelectMenu`_ has been renamed to <DocsLink type="class" parent="StringSelectMenuBuilder" />.
- _`StringSelectMenuBuilder#addOption()`_ has been removed. Use <DocsLink type="class" parent="StringSelectMenuBuilder" symbol="addOptions" brackets /> instead.
### MessageEmbed
- _`MessageEmbed`_ has now been renamed to <DocsLink type="class" parent="EmbedBuilder" />.
- <DocsLink package="builders" type="Class" parent="EmbedBuilder" symbol="setAuthor" brackets /> now accepts a sole <DocsLink
package="builders"
type="TypeAlias"
parent="EmbedAuthorOptions"
/> object.
- <DocsLink package="builders" type="Class" parent="EmbedBuilder" symbol="setFooter" brackets /> now accepts a sole <DocsLink
package="builders"
type="TypeAlias"
parent="EmbedFooterOptions"
/> object.
- _`EmbedBuilder#addField()`_ has been removed. Use <DocsLink package="builders" type="Class" parent="EmbedBuilder" symbol="addFields" brackets/> instead.
<CH.Code>
```diff
- new MessageEmbed().addField('Inline field title', 'Some value here', true);
+ new EmbedBuilder().addFields([
+ { name: 'one', value: 'one', inline: true },
+ { name: 'two', value: 'two', inline: true },
+]);
```
</CH.Code>
### Modal
- _`Modal`_ has been renamed <DocsLink type="class" parent="ModalBuilder" />.
<CH.Code>
```diff
- const modal = new Modal();
+ const modal = new ModalBuilder();
```
</CH.Code>
### PartialTypes
The _`PartialTypes`_ string array has been removed. Use the <DocsLink type="typedef" parent="Partials" /> enum instead.
In addition to this, there is now a new partial: _`Partials.ThreadMember`_.
### Permissions
The thread permissions _`USE_PUBLIC_THREADS`_ and _`USE_PRIVATE_THREADS`_ have been removed as they are deprecated in the API. Use _`CREATE_PUBLIC_THREADS`_ and _`CREATE_PRIVATE_THREADS`_ respectively.
_`ManageEmojisAndStickers`_ has been deprecated due to API changes. Its replacement is _`ManageGuildExpressions`_.[^7]
### PermissionOverwritesManager
Overwrites are now keyed by the _`PascalCase`_ permission key rather than the _`SCREAMING_SNAKE_CASE`_ permission key.
### REST Events
#### apiRequest
This REST event has been removed as discord.js now uses [Undici](https://github.com/nodejs/undici) as the underlying request handler. You must now use a [Diagnostics Channel](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel). Here is a simple example:
<CH.Code>
```js JavaScript
import diagnosticsChannel from 'node:diagnostics_channel';
diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
const { request } = data;
console.log(request.method); // Log the method
console.log(request.path); // Log the path
console.log(request.headers); // Log the headers
console.log(request); // Or just log everything!
});
```
```ts TypeScript
import diagnosticsChannel from 'node:diagnostics_channel';
import { type DiagnosticsChannel } from 'undici';
diagnosticsChannel.channel('undici:request:create').subscribe((data) => {
const { request } = data as DiagnosticsChannel.RequestCreateMessage;
console.log(request.method); // Log the method
console.log(request.path); // Log the path
console.log(request.headers); // Log the headers
console.log(request); // Or just log everything!
});
```
</CH.Code>
You can find further examples at the [Undici Diagnostics Channel documentation](https://undici.nodejs.org/#/docs/api/DiagnosticsChannel).
#### apiResponse
This REST event has been renamed to _`response`_ and moved to <DocsLink type="class" parent="Client" symbol="rest"/>:
<CH.Code>
```diff
- client.on('apiResponse', ...);
+ client.rest.on('response', ...);
```
</CH.Code>
#### invalidRequestWarning
This REST event has been moved to <DocsLink type="class" parent="Client" symbol="rest"/>:
<CH.Code>
```diff
- client.on('invalidRequestWarning', ...);
+ client.rest.on('invalidRequestWarning', ...);
```
</CH.Code>
#### rateLimit
This REST event has been renamed to _`rateLimited`_ and moved to <DocsLink type="class" parent="Client" symbol="rest"/>:
<CH.Code>
```diff
- client.on('rateLimit', ...);
+ client.rest.on('rateLimited', ...);
```
</CH.Code>
### RoleManager
_`Role.comparePositions()`_ has been removed. Use <DocsLink type="class" parent="RoleManager" symbol="comparePositions" brackets/> instead.
### Sticker
<DocsLink type="class" parent="Sticker" symbol="tags" /> is now a nullable string (_`string | null`_). Previously, it
was a nullable array of strings (_`string[] | null`_).[^5]
### ThreadChannel
The _`MAX`_ helper used in _`ThreadAutoArchiveDuration`_ has been removed. Discord has since allowed any guild to use any auto archive time which makes this helper redundant.
### ThreadMemberManager
The second parameter of <DocsLink type="class" parent="ThreadMemberManager" symbol="fetch" brackets /> has been removed. The <DocsLink type="class" parent="BaseFetchOptions" /> the second parameter once was is now merged into the first parameter. In addition, the boolean helper to specify _`cache`_ has been removed.
Usage is now as follows:
<CH.Code>
```diff
// The second parameter is merged into the first parameter.
- threadMemberManager.fetch('1234567890', { cache: false, force: true });
+ threadMemberManager.fetch({ member: '1234567890', cache: false, force: true });
// The lone boolean has been removed. One must be explicit here.
- threadMemberManager.fetch(false);
+ threadMemberManager.fetch({ cache: false });
```
</CH.Code>
### Util
_`Util.removeMentions()`_ has been removed. To control mentions, you should use _`allowedMentions`_ on <DocsLink type="typedef" parent="BaseMessageOptions" /> instead.
_`Util.splitMessage()`_ has been removed. This utility method is something the developer themselves should do.
_`Util.resolveAutoArchiveMaxLimit()`_ has been removed. Discord has since allowed any guild to use any auto archive time which makes this method redundant.
Other functions in _`Util`_ have been moved to top-level exports so you can directly import them from discord.js.
<CH.Code>
```diff
- import { Util } from 'discord.js';
- Util.escapeMarkdown(message);
+ import { escapeMarkdown } from 'discord.js';
+ escapeMarkdown(message);
```
</CH.Code>
### .deleted fields have been removed
You can no longer use the _`deleted`_ property to check if a structure was deleted.[^6]
### VoiceChannel
_`VoiceChannel#editable`_ has been removed. You should use <DocsLink type="class" parent="GuildChannel" symbol="manageable"/> instead.
### VoiceRegion
_`VoiceRegion#vip`_ has been removed as it is no longer part of the API.
### Webhook
The second parameter of <DocsLink type="class" parent="Webhook" symbol="fetchMessage" brackets/> no longer allows a boolean to be passed. The _`cache`_ option in <DocsLink type="typedef" parent="WebhookFetchMessageOptions"/> should be used instead.
## Features
### ApplicationCommand
NFSW commands are supported.
### Attachment
Added support for voice message metadata fields.
### AutocompleteInteraction
<DocsLink type="class" parent="AutocompleteInteraction" symbol="commandGuildId" /> has been added which is the id of the
guild the invoked application command is registered to.
### BaseChannel
Added support for <DocsLink type="class" parent="BaseChannel" symbol="flags" />.
Store channels have been removed as they are no longer part of the API.
<DocsLink type="class" parent="BaseChannel" symbol="url" /> has been added which is a link to a channel, just like in
the client.
Additionally, new typeguards have been added:
- <DocsLink type="class" parent="BaseChannel" symbol="isDMBased" brackets />
- <DocsLink type="class" parent="BaseChannel" symbol="isTextBased" brackets />
- <DocsLink type="class" parent="BaseChannel" symbol="isVoiceBased" brackets />
### BaseInteraction
Added <DocsLink type="class" parent="BaseInteraction" symbol="isRepliable" brackets /> to check whether a given interaction can be replied to.
### ClientApplication
Added support for role connection metadata.
### Collection
- Added <DocsLink package="collection" type="Class" parent="Collection" symbol="merge" brackets/> and <DocsLink package="collection" type="Class" parent="Collection" symbol="combineEntries" brackets/>.
- Added <DocsLink package="collection" type="TypeAlias" parent="ReadonlyCollection"/> which indicates an immutable _`Collection`_.
### Collector
A new <DocsLink type="class" parent="Collector" symbol="e-ignore"/> event has been added which is emitted whenever an element is not collected by the collector.
Component collector options now use the <DiscordAPITypesLink type="enum" parent="ComponentType" /> enum values:
<CH.Code>
```diff
+ import { ComponentType } from 'discord.js';
const collector = interaction.channel.createMessageComponentCollector({
filter,
- componentType: 'BUTTON',
+ componentType: ComponentType.Button,
time: 20000
});
```
</CH.Code>
### CommandInteraction
<DocsLink type="class" parent="CommandInteraction" symbol="commandGuildId" /> has been added which is the id of the
guild the invoked application command is registered to.
### CommandInteractionOptionResolver
<DocsLink type="class" parent="CommandInteractionOptionResolver" symbol="getChannel" brackets /> now has a third
parameter which narrows the channel type.
### Events
Added support for <DocsLink type="class" parent="Client" symbol="e-guildAuditLogEntryCreate" /> event.
### ForumChannel
Added support for forum channels.
Added support for <DocsLink type="class" parent="ForumChannel" symbol="defaultForumLayout" />.
### Guild
Added support for <DocsLink type="class" parent="Guild" symbol="setMFALevel" brackets /> which sets the guild's MFA level.
Added support for <DocsLink type="class" parent="Guild" symbol="maxVideoChannelUsers"/>. which indicates the maximum number of video channel users.
Added support for <DocsLink type="class" parent="Guild" symbol="maxStageVideoChannelUsers" />. which indicates the maximum number of video channel users for stage channels.
Added support for <DocsLink type="class" parent="Guild" symbol="disableInvites" brackets />. which disables the guild's invites.
Added support for the _`after`_ parameter in <DocsLink type="class" parent="Guild" symbol="fetchAuditLogs" brackets />.
### GuildChannelManager
_`videoQualityMode`_ may be used whilst creating a channel to initially set the camera video quality mode.
### GuildEmojiManager
Added <DocsLink type="class" parent="GuildEmojiManager" symbol="delete" brackets /> and <DocsLink type="class" parent="GuildEmojiManager" symbol="edit" brackets /> for managing existing guild emojis.
### GuildForumThreadManager
Added <DocsLink type="class" parent="GuildForumThreadManager" /> as manager for threads in forum channels.
### GuildMember
Added support for <DocsLink type="class" parent="GuildMember" symbol="flags"/>.
### GuildMembersChunk
This object now supports the _`notFound`_ property.
### GuildMemberManager
Added <DocsLink type="class" parent="GuildMemberManager" symbol="fetchMe" brackets /> to fetch the client user in the guild.
Added <DocsLink type="class" parent="GuildMemberManager" symbol="addRole" brackets /> and <DocsLink type="class" parent="GuildMemberManager" symbol="removeRole" brackets />. These methods allow a single addition or removal of a role respectively to a guild member, even if uncached.
### GuildTextThreadManager
Added <DocsLink type="class" parent="GuildTextThreadManager" /> as manager for threads in text channels and announcement channels.
### Message
<DocsLink type="class" parent="Message" symbol="position" /> has been added as an approximate position in a thread.
Added support for role subscription data.
### MessageReaction
Added <DocsLink type="class" parent="MessageReaction" symbol="react" brackets /> to make the client user react with the reaction the class belongs to.
### Role
Added support for role subscriptions.
Added support for _`Role#tags#guildConnections`_.
### StageChannel
Stage channels now allow messages to be sent in them, much like voice channels.
### Sticker
Added support for GIF stickers.
### ThreadMemberManager
The new _`withMember`_ options returns the associated guild member with the thread member.
When fetching multiple thread members alongside _`withMember`_, paginated results will be returned. The _`after`_ and _`limit`_ option are supported in this scenario.
### Webhook
Added <DocsLink type="class" parent="Webhook" symbol="applicationId" />.
Added the _`threadName`_ property in <DocsLink type="typedef" parent="WebhookMessageCreateOptions"/> which allows a webhook to create a post in a forum channel.
### WebSocketManager
discord.js uses <DocsLink package="ws" /> internally.
[^1]: https://github.com/discordjs/discord.js/pull/7188
[^2]: https://github.com/discordjs/discord.js/pull/6492
[^3]: https://github.com/discordjs/discord.js/pull/7669
[^4]: https://github.com/discordjs/discord.js/issues/6546
[^5]: https://github.com/discordjs/discord.js/pull/8010
[^6]: https://github.com/discordjs/discord.js/issues/7091
[^7]: https://github.com/discord/discord-api-docs/pull/6017

View File

@@ -1,27 +0,0 @@
'use client';
import {
type PropsWithChildren,
type Dispatch,
type SetStateAction,
createContext,
useContext,
useState,
useMemo,
} from 'react';
export const NavContext = createContext<{ opened: boolean; setOpened: Dispatch<SetStateAction<boolean>> }>({
opened: false,
setOpened: (_) => {},
});
export const NavProvider = ({ children }: PropsWithChildren) => {
const [opened, setOpened] = useState(false);
const value = useMemo(() => ({ opened, setOpened }), [opened]);
return <NavContext.Provider value={value}>{children}</NavContext.Provider>;
};
export function useNav() {
return useContext(NavContext);
}

View File

@@ -0,0 +1,7 @@
import { loader } from 'fumadocs-core/source';
import { docs } from '../../.source';
export const source = loader({
baseUrl: '/guide',
source: docs.toFumadocsSource(),
});

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