Compare commits
714 Commits
@discordjs
...
@discordjs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44696c0a6a | ||
|
|
b5d8b69452 | ||
|
|
7430c8e4c8 | ||
|
|
1a10f48bc3 | ||
|
|
e592852e42 | ||
|
|
8376e2dbcd | ||
|
|
ed68a1af5b | ||
|
|
ebf9991df7 | ||
|
|
31e67c4316 | ||
|
|
2f4bfedca1 | ||
|
|
2127b32d26 | ||
|
|
12553da135 | ||
|
|
decbce4010 | ||
|
|
9922151266 | ||
|
|
f0120538bb | ||
|
|
650f4ddfb2 | ||
|
|
56d086022f | ||
|
|
909a02e2ad | ||
|
|
ac0851b5b1 | ||
|
|
1ef42e4e7b | ||
|
|
db346e014f | ||
|
|
8f5b167483 | ||
|
|
ec37f137fd | ||
|
|
f9828034cd | ||
|
|
cb77fd02d0 | ||
|
|
7e06f68185 | ||
|
|
d2754802cc | ||
|
|
7ae0c529f2 | ||
|
|
7332b7bae3 | ||
|
|
33a82b7bce | ||
|
|
d0c82561b8 | ||
|
|
256677b435 | ||
|
|
ee7d2fd4c8 | ||
|
|
65bc0adbf4 | ||
|
|
fd4ba5eaba | ||
|
|
153d2403ad | ||
|
|
8ed5c1beb6 | ||
|
|
09f65b724b | ||
|
|
291f36cd73 | ||
|
|
b2fabd130a | ||
|
|
abefc4f809 | ||
|
|
d6873b7159 | ||
|
|
017f9b1ed4 | ||
|
|
e74aa7f6b0 | ||
|
|
ff85481d3e | ||
|
|
68c9cb37bc | ||
|
|
5152abf728 | ||
|
|
8b400ca975 | ||
|
|
88cd9d9060 | ||
|
|
5a70057826 | ||
|
|
0bcc18a0bd | ||
|
|
b5213664fa | ||
|
|
6e348ffd1d | ||
|
|
e7cbc1bf11 | ||
|
|
53d8e87d7f | ||
|
|
fc10774461 | ||
|
|
68d5712dea | ||
|
|
b2658ce504 | ||
|
|
3cc50b9e95 | ||
|
|
c0e3629f64 | ||
|
|
7083df7cef | ||
|
|
caeb1cbfdb | ||
|
|
4f3c13628e | ||
|
|
94097d365a | ||
|
|
8af0b38b6c | ||
|
|
66097e0cb0 | ||
|
|
bf9aa1858d | ||
|
|
179392d6d7 | ||
|
|
ea807e3eed | ||
|
|
ef29b5e51f | ||
|
|
cb3826ce6d | ||
|
|
d7a45a0567 | ||
|
|
49b91315f7 | ||
|
|
5ffabb119f | ||
|
|
eb46e3a5ad | ||
|
|
e8f63617a2 | ||
|
|
b05be9ec08 | ||
|
|
9d8179c6a7 | ||
|
|
f92be4fb94 | ||
|
|
c39faa94f6 | ||
|
|
7b7cc6fde4 | ||
|
|
05fbe992e3 | ||
|
|
698983b203 | ||
|
|
8b7ce2b61d | ||
|
|
e17323c15c | ||
|
|
f75f13d75b | ||
|
|
d587467a38 | ||
|
|
5bfb61d5b8 | ||
|
|
c5d5840fef | ||
|
|
a4bf975f49 | ||
|
|
c2b677759b | ||
|
|
ac83ada306 | ||
|
|
02ffce8173 | ||
|
|
caba122d20 | ||
|
|
7b8966bca1 | ||
|
|
3ed668e539 | ||
|
|
0a9d57b011 | ||
|
|
a31e605e09 | ||
|
|
7556db243d | ||
|
|
4c2955a5de | ||
|
|
5f72d8b645 | ||
|
|
a5d2ce2059 | ||
|
|
e548e6a10b | ||
|
|
6fd331dd52 | ||
|
|
32297d4717 | ||
|
|
1b4f69b00a | ||
|
|
1ea7664aa3 | ||
|
|
723c0b9b55 | ||
|
|
f0dd41fc93 | ||
|
|
b6c0ab8a41 | ||
|
|
6120971ef8 | ||
|
|
87ec3922a3 | ||
|
|
3f006cd33c | ||
|
|
4bdd120e62 | ||
|
|
c0ea782dd4 | ||
|
|
ca21dc0f3b | ||
|
|
4a57b3947a | ||
|
|
41d1c2eefc | ||
|
|
60c70389a4 | ||
|
|
f06d12fd73 | ||
|
|
dc31b76465 | ||
|
|
ba90f14f9b | ||
|
|
7b76b0b7e7 | ||
|
|
63939f8219 | ||
|
|
33ec49d5bf | ||
|
|
d923d0ab96 | ||
|
|
62332c2720 | ||
|
|
7af3c3b6f1 | ||
|
|
5730866073 | ||
|
|
9f68d73706 | ||
|
|
0ac3e766bd | ||
|
|
76a7021452 | ||
|
|
103cb16be0 | ||
|
|
baa6c69835 | ||
|
|
f85022162d | ||
|
|
35bfba0c50 | ||
|
|
ecfe4e3f1c | ||
|
|
2628659747 | ||
|
|
01d75c8b8b | ||
|
|
b64d657241 | ||
|
|
7e51ea0ada | ||
|
|
aec44a0c93 | ||
|
|
e745b95677 | ||
|
|
9effd82abe | ||
|
|
628759bcff | ||
|
|
a306219673 | ||
|
|
c0f7a1a89a | ||
|
|
a7eab50ee3 | ||
|
|
ace974fc1f | ||
|
|
d9137c3658 | ||
|
|
b7fadb350a | ||
|
|
1f944b889f | ||
|
|
b187a18e9c | ||
|
|
0b8651cf85 | ||
|
|
bf92172d80 | ||
|
|
b2ec865765 | ||
|
|
3f8656115b | ||
|
|
883f6e9202 | ||
|
|
2ea2a85e63 | ||
|
|
f063625836 | ||
|
|
6398e46043 | ||
|
|
d24dbf7d22 | ||
|
|
3c231ae81a | ||
|
|
9f63eb977f | ||
|
|
c69f512450 | ||
|
|
4a07f9eaa1 | ||
|
|
64cd53c4c2 | ||
|
|
d79aa2d0d0 | ||
|
|
822b7f234a | ||
|
|
8ca407e089 | ||
|
|
0126d9b810 | ||
|
|
e9931229ae | ||
|
|
1486bc9336 | ||
|
|
16fcdc3687 | ||
|
|
8622939229 | ||
|
|
2487e3bf76 | ||
|
|
578bc951bd | ||
|
|
1244854e13 | ||
|
|
b1e190c4f0 | ||
|
|
fc8ed816e6 | ||
|
|
abb7226af3 | ||
|
|
30ceaf7e47 | ||
|
|
9b40a79b3e | ||
|
|
0b12d6fa10 | ||
|
|
b106956308 | ||
|
|
6f1f465a77 | ||
|
|
eb98372dcd | ||
|
|
5048a3d17a | ||
|
|
f0497343f1 | ||
|
|
f6f15d8e87 | ||
|
|
14bbc9150a | ||
|
|
a7f816eeb7 | ||
|
|
802b2394b0 | ||
|
|
c446a84570 | ||
|
|
9cf0a4904b | ||
|
|
25dc146247 | ||
|
|
a2b08aaf3b | ||
|
|
eba9cc6038 | ||
|
|
145eb2fc5d | ||
|
|
8444576f45 | ||
|
|
6d43e26676 | ||
|
|
2fc3d86f56 | ||
|
|
8a8d519c9c | ||
|
|
669c3cd256 | ||
|
|
678ceaa014 | ||
|
|
0785353efe | ||
|
|
8323926304 | ||
|
|
bccc2c8e89 | ||
|
|
1d72663e92 | ||
|
|
d0a2a6227d | ||
|
|
735e0bf52e | ||
|
|
1c5b78fd21 | ||
|
|
053da5bc91 | ||
|
|
fc9653f5ae | ||
|
|
22ac6b4660 | ||
|
|
d14d47b62f | ||
|
|
a9f003ac9b | ||
|
|
1d4cdee321 | ||
|
|
8e1afaebdb | ||
|
|
32523325c6 | ||
|
|
7a9e52e63a | ||
|
|
d11edc6397 | ||
|
|
96304d7cc8 | ||
|
|
f9e9bfdedc | ||
|
|
ce1f5c8d47 | ||
|
|
03fb5b0a2f | ||
|
|
ce991dd1d8 | ||
|
|
dbca93098c | ||
|
|
dd5a08944c | ||
|
|
8e98ba94d2 | ||
|
|
74dc8c10d5 | ||
|
|
8d07ea9a62 | ||
|
|
d8e774138d | ||
|
|
55c3ee20ae | ||
|
|
c3341570d9 | ||
|
|
f3ce4a75d0 | ||
|
|
4ffdada4f7 | ||
|
|
8b3d006118 | ||
|
|
d08a57cadd | ||
|
|
0dc68445a1 | ||
|
|
a7ad7e75ce | ||
|
|
f79ccb4971 | ||
|
|
6f2b223c8b | ||
|
|
a4777aa9b0 | ||
|
|
f072d3d916 | ||
|
|
0238588067 | ||
|
|
1d460e0434 | ||
|
|
b9c62ac0f0 | ||
|
|
df46ab8061 | ||
|
|
b7eb96d456 | ||
|
|
f77612a55e | ||
|
|
9b4116b659 | ||
|
|
8a91d7c256 | ||
|
|
3b7ba4062e | ||
|
|
edadb9fe5d | ||
|
|
4bdb0593ae | ||
|
|
fd97da9b6c | ||
|
|
d5dcddd350 | ||
|
|
40324574eb | ||
|
|
1398af66f0 | ||
|
|
682e0e1802 | ||
|
|
13baf75cae | ||
|
|
1d6b31b78d | ||
|
|
5f093dde24 | ||
|
|
b58e6a65ad | ||
|
|
204f4dd7c4 | ||
|
|
249ba0a9a6 | ||
|
|
92933c2b61 | ||
|
|
abd3fc8ceb | ||
|
|
84059b6b25 | ||
|
|
6da405668f | ||
|
|
58d2a1e6d7 | ||
|
|
7b5c688844 | ||
|
|
28bc4f42c6 | ||
|
|
5b4672bad3 | ||
|
|
a57b9ba5c4 | ||
|
|
32da9b3868 | ||
|
|
70806b401e | ||
|
|
0674820723 | ||
|
|
2d5bce274c | ||
|
|
331dedcb9d | ||
|
|
103e1bd843 | ||
|
|
ffafde0b6b | ||
|
|
28422eea58 | ||
|
|
c826ad3ade | ||
|
|
17559becef | ||
|
|
b31a23b37c | ||
|
|
8e4f77a63b | ||
|
|
b16ab8c69f | ||
|
|
cf8570c19c | ||
|
|
f0ab393411 | ||
|
|
11e02f1e5d | ||
|
|
206523587a | ||
|
|
ac3bc6a2db | ||
|
|
af295acedc | ||
|
|
caa5c0332f | ||
|
|
434f696397 | ||
|
|
6062d361fb | ||
|
|
2ecb862e76 | ||
|
|
360936140b | ||
|
|
0b56184ba7 | ||
|
|
a55545850a | ||
|
|
f16b11a91d | ||
|
|
0fb2694871 | ||
|
|
ee030003ec | ||
|
|
29c51be1f4 | ||
|
|
43a78be70b | ||
|
|
92c0c60519 | ||
|
|
ba3e0ed348 | ||
|
|
f7ce9f8533 | ||
|
|
00990c93ae | ||
|
|
c076b0d8cb | ||
|
|
d297fb0b69 | ||
|
|
24c128d649 | ||
|
|
ec7c6e3d3e | ||
|
|
6dfb9bbc48 | ||
|
|
4644e45e85 | ||
|
|
1e001601c8 | ||
|
|
1aec243b1d | ||
|
|
191951ac28 | ||
|
|
4fb4492b17 | ||
|
|
abb968de81 | ||
|
|
d9e53093f5 | ||
|
|
e5678f4656 | ||
|
|
9f18036078 | ||
|
|
474eae0afc | ||
|
|
caeb66e150 | ||
|
|
7623fc552e | ||
|
|
230c43e97d | ||
|
|
4e3fa586b5 | ||
|
|
6bb1474d20 | ||
|
|
27bbc8fe68 | ||
|
|
e2cde5daa0 | ||
|
|
0960457108 | ||
|
|
cd6b365b17 | ||
|
|
19e1f5d0ca | ||
|
|
3621e5efbd | ||
|
|
d2f5b5b539 | ||
|
|
9ed11a4c19 | ||
|
|
e42fd16369 | ||
|
|
dd44e8b6ec | ||
|
|
3bef9018c0 | ||
|
|
23a0b6ccf2 | ||
|
|
b3f7c32f7f | ||
|
|
0dba8adbd2 | ||
|
|
2b8074dd12 | ||
|
|
16bbc8aa20 | ||
|
|
7a3d18dd6d | ||
|
|
4882b17a77 | ||
|
|
8028813825 | ||
|
|
47f2990b89 | ||
|
|
e475b63f25 | ||
|
|
673262d38c | ||
|
|
7f415a2502 | ||
|
|
cda3f005b1 | ||
|
|
f9c25ddcfe | ||
|
|
74740260a7 | ||
|
|
1008e3d4a7 | ||
|
|
17ab0e652c | ||
|
|
872ce801a0 | ||
|
|
0bf3df30da | ||
|
|
20680efbc9 | ||
|
|
7701331b1c | ||
|
|
0be85fd101 | ||
|
|
e147c5bd64 | ||
|
|
2f1ec7401c | ||
|
|
0f83402985 | ||
|
|
d97cd936fd | ||
|
|
812f7f1ea8 | ||
|
|
7d2507279c | ||
|
|
c31a5cfcc8 | ||
|
|
acdafe60c7 | ||
|
|
4fd42528fe | ||
|
|
ebaf158006 | ||
|
|
7116647947 | ||
|
|
c99b808882 | ||
|
|
a1dddd6b2c | ||
|
|
b3db9eef32 | ||
|
|
501945215b | ||
|
|
e82b2e49f5 | ||
|
|
5f42b5af30 | ||
|
|
35e79b389d | ||
|
|
5dc7946df2 | ||
|
|
1e00f5789e | ||
|
|
85cb0f25c7 | ||
|
|
3cc893a282 | ||
|
|
fc99bf431a | ||
|
|
4ab1d09997 | ||
|
|
d09ef1e425 | ||
|
|
d56590a11d | ||
|
|
c052f56f3e | ||
|
|
cb856860b7 | ||
|
|
4cf265c7c6 | ||
|
|
3ec7ef07a0 | ||
|
|
90e7aea443 | ||
|
|
1211c7fc10 | ||
|
|
84a4b1f58a | ||
|
|
193b252672 | ||
|
|
bc06cc638d | ||
|
|
d08da8a212 | ||
|
|
5360099e5f | ||
|
|
fd4844ddb9 | ||
|
|
8e69efde04 | ||
|
|
2447165c82 | ||
|
|
c97977a3e8 | ||
|
|
7666a6c341 | ||
|
|
9d8966fe24 | ||
|
|
4d128acac5 | ||
|
|
831d6506cb | ||
|
|
c5b96a185c | ||
|
|
afa27b15c5 | ||
|
|
4d7283933d | ||
|
|
452e94fd3e | ||
|
|
6c6fe74dd8 | ||
|
|
0e2a09571c | ||
|
|
0fab869e51 | ||
|
|
64a4041a05 | ||
|
|
38275fc53d | ||
|
|
aac8acc22b | ||
|
|
6ef4754d40 | ||
|
|
b8a31360a2 | ||
|
|
5b053cf82e | ||
|
|
e72b986939 | ||
|
|
3a96ce7970 | ||
|
|
359f688555 | ||
|
|
3161e1a1ac | ||
|
|
4d8361c711 | ||
|
|
d6e4d149fd | ||
|
|
480c85c9c3 | ||
|
|
b45b99f92b | ||
|
|
5137bfc17d | ||
|
|
fca3dada2a | ||
|
|
d070de6da7 | ||
|
|
a3183cfad4 | ||
|
|
aba307341d | ||
|
|
c479d39a6b | ||
|
|
52c2818b25 | ||
|
|
d03cf6176c | ||
|
|
11e77f7f86 | ||
|
|
2b1e88b5fa | ||
|
|
e5bfe2c7c2 | ||
|
|
a7deb8f898 | ||
|
|
b4e2c0c4d5 | ||
|
|
33113614e0 | ||
|
|
26556390a3 | ||
|
|
5494791313 | ||
|
|
c258bdf083 | ||
|
|
ff5dd1fcb4 | ||
|
|
a38c58dbd0 | ||
|
|
ec43c184fe | ||
|
|
c25e8ad78b | ||
|
|
3f17ff23bf | ||
|
|
a7dc588d9f | ||
|
|
2291429d30 | ||
|
|
bf7326729d | ||
|
|
124d8123b8 | ||
|
|
0b61dbf720 | ||
|
|
ba6797e742 | ||
|
|
7fd9ed8f13 | ||
|
|
b6bba9901b | ||
|
|
2130aae321 | ||
|
|
80b9738957 | ||
|
|
5d8bd030d6 | ||
|
|
e9920a9c98 | ||
|
|
6d248051cf | ||
|
|
798466a696 | ||
|
|
1275918ca8 | ||
|
|
a7d49e56fc | ||
|
|
34ba9d1c4c | ||
|
|
77ed407f6a | ||
|
|
4fc2c60a3b | ||
|
|
9f4446b10f | ||
|
|
78d4295a40 | ||
|
|
5a3c9996e0 | ||
|
|
4fff6076e7 | ||
|
|
4bda24678a | ||
|
|
9ae461d84d | ||
|
|
160487d866 | ||
|
|
41e4e10b48 | ||
|
|
200ab91f52 | ||
|
|
3839958e3f | ||
|
|
58c1b51c5c | ||
|
|
6a2d0d8e96 | ||
|
|
335695c698 | ||
|
|
8e520f946a | ||
|
|
59a7e52224 | ||
|
|
af837debe3 | ||
|
|
df42fdfc42 | ||
|
|
5f667c0c82 | ||
|
|
90cbd2bbd5 | ||
|
|
f50382e1ce | ||
|
|
1b03631205 | ||
|
|
a490adfe36 | ||
|
|
f097f0bc1f | ||
|
|
1d63d3ce1c | ||
|
|
6d25fb8856 | ||
|
|
86a9be7d33 | ||
|
|
82165d4f80 | ||
|
|
ee455c812e | ||
|
|
0d687b5606 | ||
|
|
748d7271c4 | ||
|
|
830c670c61 | ||
|
|
74ec7be346 | ||
|
|
96b62b6539 | ||
|
|
8a6ee906a7 | ||
|
|
1fb7b30963 | ||
|
|
45c9659080 | ||
|
|
07a5cd7048 | ||
|
|
d0e3c972b4 | ||
|
|
a05386a46c | ||
|
|
3b0197bd8e | ||
|
|
d1245418f9 | ||
|
|
e7d4d41640 | ||
|
|
ce1807dc80 | ||
|
|
34d3917a28 | ||
|
|
9e624abf1a | ||
|
|
8c4b9865e1 | ||
|
|
dbad1c468b | ||
|
|
4ffd7f9f80 | ||
|
|
660e212e83 | ||
|
|
70dd757ec3 | ||
|
|
b5d4b2d78b | ||
|
|
78d013f87c | ||
|
|
21d61ca260 | ||
|
|
b316ac7cc4 | ||
|
|
ed94b3d9ec | ||
|
|
dcbbecfed2 | ||
|
|
0c5e37d515 | ||
|
|
656e9550db | ||
|
|
3a7e93df57 | ||
|
|
66092cad8b | ||
|
|
ec230faa4d | ||
|
|
cd13a4a902 | ||
|
|
dda2895bfb | ||
|
|
f0b77348d3 | ||
|
|
b0a9131b1c | ||
|
|
29be5b570b | ||
|
|
d677c31161 | ||
|
|
f6ef92ad6a | ||
|
|
52a9e213c2 | ||
|
|
b7e62380f2 | ||
|
|
cafde77d73 | ||
|
|
b7d4e55419 | ||
|
|
5aeed99350 | ||
|
|
452dec57ca | ||
|
|
64f814066c | ||
|
|
33a7a5cbdc | ||
|
|
edf83f02ea | ||
|
|
25bd771559 | ||
|
|
f2ca0ca6f9 | ||
|
|
6712de9752 | ||
|
|
28cd293f14 | ||
|
|
3f5690afe1 | ||
|
|
015ab69956 | ||
|
|
caecc574f0 | ||
|
|
3bf30b1e6d | ||
|
|
103a3584c9 | ||
|
|
bf65b37d1a | ||
|
|
7e6dbaaed9 | ||
|
|
1a6ddbbe7b | ||
|
|
32f9056b15 | ||
|
|
3648f6d567 | ||
|
|
bddb6a461c | ||
|
|
fe34f48efb | ||
|
|
30a8d3231f | ||
|
|
1ed605eaa4 | ||
|
|
787654816d | ||
|
|
f0b68d5736 | ||
|
|
75256153a9 | ||
|
|
33ae7df000 | ||
|
|
feb3bdda0a | ||
|
|
e78c9c9ee9 | ||
|
|
43f62bb667 | ||
|
|
96c8d21f95 | ||
|
|
10ba0080cc | ||
|
|
0b979b04f2 | ||
|
|
a4d1862982 | ||
|
|
34531c45e3 | ||
|
|
8198da5cd0 | ||
|
|
ba10637529 | ||
|
|
68c3d8743e | ||
|
|
a51f7215ec | ||
|
|
c271e05223 | ||
|
|
d2e74003d5 | ||
|
|
fd1c24036f | ||
|
|
eb9ad46d4f | ||
|
|
5bd6b28b3e | ||
|
|
f6db285c07 | ||
|
|
68ade870f8 | ||
|
|
c7a205f7b9 | ||
|
|
c5750d59f5 | ||
|
|
31d5930464 | ||
|
|
cdd9214212 | ||
|
|
fa010b5162 | ||
|
|
6b20645740 | ||
|
|
50d55bd6b8 | ||
|
|
2d9dfa3c6e | ||
|
|
ab238a9046 | ||
|
|
94ee60d3d4 | ||
|
|
f10f4cdcd8 | ||
|
|
d95197cc78 | ||
|
|
e0c8282490 | ||
|
|
741b3c8e27 | ||
|
|
819a1fdf7d | ||
|
|
ce9afbb8e4 | ||
|
|
b2776c22d4 | ||
|
|
525bf031a5 | ||
|
|
27d8deb471 | ||
|
|
11b1739319 | ||
|
|
b83e0c0caf | ||
|
|
8421f9203b | ||
|
|
cb3dca4ae0 | ||
|
|
002d6a5aed | ||
|
|
c4653f97b1 | ||
|
|
e24970e3c3 | ||
|
|
65dc8d677e | ||
|
|
0ffbef506a | ||
|
|
5d3dd55a26 | ||
|
|
70b42bb64a | ||
|
|
af04992ed3 | ||
|
|
bbdb5d980b | ||
|
|
7279f9c31b | ||
|
|
5e5853a4e8 | ||
|
|
cd17aad720 | ||
|
|
ee36d60dc6 | ||
|
|
c34c02ab8d | ||
|
|
31f658247f | ||
|
|
a3799f9ebb | ||
|
|
a061233510 | ||
|
|
203bc4a2cf | ||
|
|
65d1879c0a | ||
|
|
c6f285b7b0 | ||
|
|
2eeaad6f27 | ||
|
|
f1ac17c961 | ||
|
|
db2b0333d9 | ||
|
|
94f7ca9474 | ||
|
|
e68effa822 | ||
|
|
358c3f4a46 | ||
|
|
268a9b4be5 | ||
|
|
95e6d6ede0 | ||
|
|
17867f9154 | ||
|
|
3a77ce0b18 | ||
|
|
23e183a9ac | ||
|
|
b3c3a94d5d | ||
|
|
8610700c87 | ||
|
|
db663a55c2 | ||
|
|
0673ea377a | ||
|
|
2681929e42 | ||
|
|
0a138dab95 | ||
|
|
415513696c | ||
|
|
90a98fee16 | ||
|
|
386c41f24f | ||
|
|
d54bf5d286 | ||
|
|
e5ec1c4dbc | ||
|
|
ad9ab2b177 | ||
|
|
4df491ce85 | ||
|
|
0a44b05db8 | ||
|
|
b4e28a8ff6 | ||
|
|
9c0f190de1 | ||
|
|
093117d938 | ||
|
|
e53d162198 | ||
|
|
51eadf3737 | ||
|
|
552ec72542 | ||
|
|
ac7bf692bf | ||
|
|
9964454c29 | ||
|
|
476b7d519c | ||
|
|
10a6c4287d | ||
|
|
a2eebf6c66 | ||
|
|
96053babe1 | ||
|
|
f527dea36e | ||
|
|
c7391db11b | ||
|
|
c5176be14b | ||
|
|
fbe67e1025 | ||
|
|
3bb9c0e5c3 | ||
|
|
9c8b3102ce | ||
|
|
2392a6f5de | ||
|
|
c0f079d232 | ||
|
|
d8077c6839 | ||
|
|
d4b41dd081 | ||
|
|
0415300243 | ||
|
|
caee94897f | ||
|
|
b3346f4b9b | ||
|
|
2791c86cdf | ||
|
|
c8f1690896 | ||
|
|
da9107c007 | ||
|
|
f57d6768ad | ||
|
|
d7b8357dcb | ||
|
|
16810f3e41 | ||
|
|
598f61b992 | ||
|
|
50401453e7 | ||
|
|
94bdcaca62 | ||
|
|
eea139b346 | ||
|
|
50822f5254 | ||
|
|
f2b267c079 | ||
|
|
b2eea1c900 | ||
|
|
3ae2633c3f | ||
|
|
3937b402c0 | ||
|
|
256c4f955c | ||
|
|
33cdcdbb7a | ||
|
|
bc466a5997 | ||
|
|
127931d1df | ||
|
|
5259639c2c | ||
|
|
5de9b80814 | ||
|
|
bc4fbcef2e | ||
|
|
3279b40912 | ||
|
|
1afae909d7 | ||
|
|
65cb36166f | ||
|
|
ecc6600df2 | ||
|
|
314d76e907 | ||
|
|
769ea0bfe7 | ||
|
|
8b979c0245 | ||
|
|
5475767c2c | ||
|
|
86d8fbc023 | ||
|
|
fba9710fc9 |
56
.dockerignore
Normal file
@@ -0,0 +1,56 @@
|
||||
# Packages
|
||||
node_modules/
|
||||
|
||||
# Log files
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Env
|
||||
.env
|
||||
|
||||
# Dist
|
||||
dist/
|
||||
|
||||
# Miscellaneous
|
||||
.tmp/
|
||||
.vscode/*
|
||||
.idea/
|
||||
.DS_Store
|
||||
.turbo
|
||||
tsconfig.tsbuildinfo
|
||||
coverage/
|
||||
__tests__/
|
||||
|
||||
# yarn
|
||||
.pnp.*
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# Cache
|
||||
.prettiercache
|
||||
.eslintcache
|
||||
|
||||
# Docker specific
|
||||
.cliff-jumperrc.json
|
||||
api-extractor.json
|
||||
.eslintrc.json
|
||||
.lintstagedrc.cjs
|
||||
.lintstagedrc.cjs
|
||||
.prettierignore
|
||||
.prettierrc.js
|
||||
.prettierrc.cjs
|
||||
cliff.toml
|
||||
CHANGELOG.md
|
||||
README.md
|
||||
tsconfig.eslint.json
|
||||
docs/
|
||||
14
.eslintrc.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": ["neon/common", "neon/node", "neon/typescript", "neon/prettier"],
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.eslint.json"
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/consistent-type-definitions": ["error", "interface"]
|
||||
},
|
||||
"ignorePatterns": ["**/dist/*"],
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
||||
11
.github/.kodiak.toml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
version = 1
|
||||
|
||||
[merge]
|
||||
require_automerge_label = false
|
||||
blocking_labels = ['blocked']
|
||||
method = 'squash'
|
||||
|
||||
[merge.message]
|
||||
title = 'pull_request_title'
|
||||
strip_html_comments = true
|
||||
include_coauthors = true
|
||||
30
.github/CONTRIBUTING.md
vendored
@@ -16,3 +16,33 @@ To get ready to work on the codebase, please do the following:
|
||||
4. Code your heart out!
|
||||
5. Run `yarn test` to run ESLint and ensure any JSDoc changes are valid
|
||||
6. [Submit a pull request](https://github.com/discordjs/discord.js/compare) (Make sure you follow the [conventional commit format](https://github.com/discordjs/discord.js/blob/main/.github/COMMIT_CONVENTION.md))
|
||||
|
||||
## Testing changes locally
|
||||
|
||||
If you want to test changes you've made locally, you can do so by using `yarn link`. This will create a symlink to your local copy of the discord.js libraries.
|
||||
|
||||
1. Create a new directory `mkdir discordjs-test` and move into it `cd discordjs-test`
|
||||
2. Initialize a new yarn 3 project `yarn init -2`
|
||||
3. Disable pnp `yarn config set nodeLinker node-modules`
|
||||
4. Now link the local discord.js project you cloned earlier `yarn link -A {PATH_TO_DISCORDJS_REPO}`
|
||||
5. Install packages you'd like to test locally `yarn add discord.js@latest`, `yarn add @discordjs/rest@latest`, etc. **Note: Make sure you use `latest` tag or else yarn will try to install the remote package from npm**
|
||||
6. Import the package in your source code and test them out!
|
||||
|
||||
### Working with TypeScript packages
|
||||
|
||||
When testing local changes, you may notice you need to manually recompile TypeScript projects on every change in order to get the latest code changes to test locally.
|
||||
|
||||
To avoid this you can use the `--watch` parameter in the package build script to automatically recompile the project when changes are detected.
|
||||
|
||||
For example, to automatically recompile the `@discordjs/rest` project when changes are detected, run `yarn turbo run build --filter=@discordjs/rest -- --watch` in the root folder of where you cloned the discord.js repo.
|
||||
|
||||
## Adding new packages
|
||||
|
||||
If you'd like to create another package under the `@discordjs` organization run the following command:
|
||||
|
||||
```bash
|
||||
yarn create-package <package-name> [package-description]
|
||||
```
|
||||
|
||||
This will create new package directory under `packages/` with the required configuration files. You can
|
||||
begin to make changes within the `src/` directory.
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -12,11 +12,15 @@ body:
|
||||
label: Which package is this bug report for?
|
||||
options:
|
||||
- discord.js
|
||||
- brokers
|
||||
- builders
|
||||
- collection
|
||||
- core
|
||||
- rest
|
||||
- proxy
|
||||
- proxy-container
|
||||
- voice
|
||||
- ws
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
@@ -50,7 +54,7 @@ body:
|
||||
id: djs-version
|
||||
attributes:
|
||||
label: Package version
|
||||
description: Which version of are you using? Run `npm list <package>` in your project directory and paste the output.
|
||||
description: Which version of the package are you using? Run `npm list <package>` in your project directory and paste the output.
|
||||
placeholder: We no longer support version 12 or earlier of discord.js
|
||||
validations:
|
||||
required: true
|
||||
@@ -127,7 +131,10 @@ body:
|
||||
- DirectMessages
|
||||
- DirectMessageReactions
|
||||
- DirectMessageTyping
|
||||
- MessageContent
|
||||
- GuildScheduledEvents
|
||||
- AutoModerationConfiguration
|
||||
- AutoModerationExecution
|
||||
multiple: true
|
||||
validations:
|
||||
required: true
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
We can only implement features that Discord publishes, documents and merges into the Discord API documentation.
|
||||
We can only implement features that Discord publishes, documents, and merges into the Discord API documentation.
|
||||
We do not implement unreleased features.
|
||||
Use Discord for questions: https://discord.gg/djs
|
||||
- type: dropdown
|
||||
@@ -16,9 +16,12 @@ body:
|
||||
- discord.js
|
||||
- builders
|
||||
- collection
|
||||
- core
|
||||
- rest
|
||||
- proxy
|
||||
- proxy-container
|
||||
- voice
|
||||
- ws
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
|
||||
47
.github/labeler.yml
vendored
@@ -1,31 +1,46 @@
|
||||
chore:
|
||||
- any: ['*']
|
||||
all: ['!packages/*', '!packages/**/*']
|
||||
apps:guide:
|
||||
- apps/guide/*
|
||||
- apps/guide/**/*
|
||||
apps:website:
|
||||
- apps/website/*
|
||||
- apps/website/**/*
|
||||
|
||||
'packages:builders':
|
||||
packages:brokers:
|
||||
- packages/brokers/*
|
||||
- packages/brokers/**/*
|
||||
packages:builders:
|
||||
- packages/builders/*
|
||||
- packages/builders/**/*
|
||||
|
||||
'packages:collection':
|
||||
packages:collection:
|
||||
- packages/collection/*
|
||||
- packages/collection/**/*
|
||||
|
||||
'packages:discord.js':
|
||||
packages:core:
|
||||
- packages/core/*
|
||||
- packages/core/**/*
|
||||
packages:discord.js:
|
||||
- packages/discord.js/*
|
||||
- packages/discord.js/**/*
|
||||
|
||||
'packages:proxy':
|
||||
packages:docgen:
|
||||
- packages/docgen/*
|
||||
- packages/docgen/**/*
|
||||
packages:proxy:
|
||||
- packages/proxy/*
|
||||
- packages/proxy/**/*
|
||||
|
||||
'packages:rest':
|
||||
packages:proxy-container:
|
||||
- packages/proxy-container/*
|
||||
- packages/proxy-container/**/*
|
||||
packages:rest:
|
||||
- packages/rest/*
|
||||
- packages/rest/**/*
|
||||
|
||||
'packages:voice':
|
||||
packages/ui:
|
||||
- packages:ui/*
|
||||
- packages:ui/**/*
|
||||
packages:util:
|
||||
- packages/util/*
|
||||
- packages/util/**/*
|
||||
packages:voice:
|
||||
- packages/voice/*
|
||||
- packages/voice/**/*
|
||||
|
||||
'packages:ws':
|
||||
packages:ws:
|
||||
- packages/ws/*
|
||||
- packages/ws/**/*
|
||||
|
||||
198
.github/labels.yml
vendored
@@ -1,94 +1,112 @@
|
||||
- name: 'api changes'
|
||||
- name: api changes
|
||||
color: '5663e9'
|
||||
- name: 'api support'
|
||||
- name: api support
|
||||
color: '5663e9'
|
||||
- name: 'backlog'
|
||||
color: '7ef7ef'
|
||||
- name: 'bug'
|
||||
color: 'd73a4a'
|
||||
- name: 'caching'
|
||||
color: '80c042'
|
||||
- name: 'chore'
|
||||
color: 'ffffff'
|
||||
- name: 'ci'
|
||||
color: '0075ca'
|
||||
- name: 'dependencies'
|
||||
color: '276bd1'
|
||||
- name: 'discussion'
|
||||
color: 'b6b1f9'
|
||||
- name: 'discord'
|
||||
- name: apps:guide
|
||||
color: fbca04
|
||||
- name: apps:website
|
||||
color: fbca04
|
||||
- name: backlog
|
||||
color: 7ef7ef
|
||||
- name: blocked
|
||||
color: fc1423
|
||||
- name: bug
|
||||
color: d73a4a
|
||||
- name: caching
|
||||
color: 80c042
|
||||
- name: chore
|
||||
color: ffffff
|
||||
- name: ci
|
||||
color: 0075ca
|
||||
- name: dependencies
|
||||
color: 276bd1
|
||||
- name: discussion
|
||||
color: b6b1f9
|
||||
- name: discord
|
||||
color: '5663e9'
|
||||
- name: 'documentation'
|
||||
color: '0075ca'
|
||||
- name: 'duplicate'
|
||||
color: 'cfd3d7'
|
||||
- name: 'error handling'
|
||||
color: '80c042'
|
||||
- name: 'feature request'
|
||||
color: 'fcf95a'
|
||||
- name: 'gateway'
|
||||
color: '80c042'
|
||||
- name: 'good first issue'
|
||||
color: '7057ff'
|
||||
- name: 'has PR'
|
||||
color: '4b1f8e'
|
||||
- name: 'help wanted'
|
||||
- name: documentation
|
||||
color: 0075ca
|
||||
- name: duplicate
|
||||
color: cfd3d7
|
||||
- name: error handling
|
||||
color: 80c042
|
||||
- name: feature request
|
||||
color: fcf95a
|
||||
- name: gateway
|
||||
color: 80c042
|
||||
- name: good first issue
|
||||
color: 7057ff
|
||||
- name: has PR
|
||||
color: 4b1f8e
|
||||
- name: help wanted
|
||||
color: '008672'
|
||||
- name: 'interactions'
|
||||
color: '80c042'
|
||||
- name: 'in progress'
|
||||
color: 'ffccd7'
|
||||
- name: 'in review'
|
||||
color: 'aed5fc'
|
||||
- name: 'invalid'
|
||||
color: 'e4e669'
|
||||
- name: 'need repro'
|
||||
color: 'c66037'
|
||||
- name: 'packages:builders'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:collection'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:discord.js'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:proxy'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:rest'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:voice'
|
||||
color: 'fbca04'
|
||||
- name: 'packages:ws'
|
||||
color: 'fbca04'
|
||||
- name: 'performance'
|
||||
color: '80c042'
|
||||
- name: 'permissions'
|
||||
color: '80c042'
|
||||
- name: 'priority:high'
|
||||
color: 'fc1423'
|
||||
- name: 'question (please use Discord instead)'
|
||||
color: 'd876e3'
|
||||
- name: 'ratelimits'
|
||||
color: '80c042'
|
||||
- name: 'refactor'
|
||||
color: '1d637f'
|
||||
- name: 'regression'
|
||||
color: 'ea8785'
|
||||
- name: 'REST'
|
||||
color: '80c042'
|
||||
- name: 'semver:major'
|
||||
color: 'c10f47'
|
||||
- name: 'semver:minor'
|
||||
color: 'e4f486'
|
||||
- name: 'semver:patch'
|
||||
color: 'e8be8b'
|
||||
- name: 'sharding'
|
||||
color: '80c042'
|
||||
- name: 'tests'
|
||||
color: 'f06dff'
|
||||
- name: 'threads'
|
||||
color: '80c042'
|
||||
- name: 'typings'
|
||||
color: '80c042'
|
||||
- name: 'utility'
|
||||
color: '80c042'
|
||||
- name: 'wontfix'
|
||||
color: 'ffffff'
|
||||
- name: interactions
|
||||
color: 80c042
|
||||
- name: in progress
|
||||
color: ffccd7
|
||||
- name: in review
|
||||
color: aed5fc
|
||||
- name: invalid
|
||||
color: e4e669
|
||||
- name: need repro
|
||||
color: c66037
|
||||
- name: packages:brokers
|
||||
color: fbca04
|
||||
- name: packages:builders
|
||||
color: fbca04
|
||||
- name: packages:collection
|
||||
color: fbca04
|
||||
- name: packages:core
|
||||
color: fbca04
|
||||
- name: packages:discord.js
|
||||
color: fbca04
|
||||
- name: packages:docgen
|
||||
color: fbca04
|
||||
- name: packages:proxy
|
||||
color: fbca04
|
||||
- name: packages:proxy-container
|
||||
color: fbca04
|
||||
- name: packages:rest
|
||||
color: fbca04
|
||||
- name: packages:ui
|
||||
color: fbca04
|
||||
- name: packages:util
|
||||
color: fbca04
|
||||
- name: packages:voice
|
||||
color: fbca04
|
||||
- name: packages:ws
|
||||
color: fbca04
|
||||
- name: performance
|
||||
color: 80c042
|
||||
- name: permissions
|
||||
color: 80c042
|
||||
- name: priority:high
|
||||
color: fc1423
|
||||
- name: question (please use Discord instead)
|
||||
color: d876e3
|
||||
- name: ratelimits
|
||||
color: 80c042
|
||||
- name: refactor
|
||||
color: 1d637f
|
||||
- name: regression
|
||||
color: ea8785
|
||||
- name: REST
|
||||
color: 80c042
|
||||
- name: semver:major
|
||||
color: c10f47
|
||||
- name: semver:minor
|
||||
color: e4f486
|
||||
- name: semver:patch
|
||||
color: e8be8b
|
||||
- name: sharding
|
||||
color: 80c042
|
||||
- name: tests
|
||||
color: f06dff
|
||||
- name: threads
|
||||
color: 80c042
|
||||
- name: typings
|
||||
color: 80c042
|
||||
- name: utility
|
||||
color: 80c042
|
||||
- name: wontfix
|
||||
color: ffffff
|
||||
|
||||
6
.github/powered-by-vercel.svg
vendored
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
124
.github/workflows/documentation.yml
vendored
@@ -3,8 +3,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'stable'
|
||||
- '!docs'
|
||||
tags:
|
||||
- '**'
|
||||
workflow_dispatch:
|
||||
@@ -12,55 +10,55 @@ on:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA to checkout'
|
||||
required: true
|
||||
ref_type:
|
||||
type: choice
|
||||
description: 'Branch or tag'
|
||||
options:
|
||||
- branch
|
||||
- tag
|
||||
required: true
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
name: Build documentation
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
if: github.repository_owner == 'discordjs'
|
||||
outputs:
|
||||
BRANCH_NAME: ${{ steps.env.outputs.BRANCH_NAME }}
|
||||
BRANCH_OR_TAG: ${{ steps.env.outputs.BRANCH_OR_TAG }}
|
||||
SHA: ${{ steps.env.outputs.SHA }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.inputs.ref || '' }}
|
||||
ref: ${{ inputs.ref || '' }}
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: yarn.lock
|
||||
|
||||
- name: Turbo cache
|
||||
id: turbo-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
turbo-${{ github.job }}-${{ github.ref_name }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
uses: ./packages/actions/src/yarnCache
|
||||
|
||||
- name: Build dependencies
|
||||
run: yarn build
|
||||
|
||||
- name: Build docs
|
||||
run: yarn docs --cache-dir=".turbo"
|
||||
run: yarn docs
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
- name: Upload docgen artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs
|
||||
name: docgen
|
||||
path: packages/*/docs/docs.json
|
||||
|
||||
- name: Set outputs for upload job
|
||||
id: env
|
||||
run: |
|
||||
echo "::set-output name=BRANCH_NAME::${GITHUB_REF_NAME}"
|
||||
echo "::set-output name=BRANCH_OR_TAG::${GITHUB_REF_TYPE}"
|
||||
echo "::set-output name=SHA::${GITHUB_SHA}"
|
||||
- name: Upload api-extractor artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: api-extractor
|
||||
path: packages/*/docs/docs.api.json
|
||||
|
||||
upload:
|
||||
name: Upload Documentation
|
||||
@@ -69,74 +67,78 @@ jobs:
|
||||
max-parallel: 1
|
||||
fail-fast: false
|
||||
matrix:
|
||||
package: ['builders', 'collection', 'discord.js', 'proxy', 'rest', 'voice']
|
||||
package: ['brokers', 'builders', 'collection', 'core', 'discord.js', 'proxy', 'rest', 'util', 'voice', 'ws']
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
BRANCH_NAME: ${{ github.event.inputs.ref || needs.build.outputs.BRANCH_NAME }}
|
||||
BRANCH_OR_TAG: ${{ needs.build.outputs.BRANCH_OR_TAG }}
|
||||
SHA: ${{ needs.build.outputs.SHA }}
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: yarn.lock
|
||||
|
||||
- name: Turbo cache
|
||||
id: turbo-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
turbo-${{ github.job }}-${{ github.ref_name }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
uses: ./packages/actions/src/yarnCache
|
||||
|
||||
- name: Build actions
|
||||
run: yarn build --cache-dir=".turbo"
|
||||
run: yarn workspace @discordjs/actions build
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
- name: Download docgen artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: docs
|
||||
name: docgen
|
||||
path: docs
|
||||
|
||||
- name: Download api-extractor artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: api-extractor
|
||||
path: docs
|
||||
|
||||
- name: Checkout docs repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: 'discordjs/docs'
|
||||
token: ${{ secrets.DJS_DOCS }}
|
||||
path: 'out'
|
||||
|
||||
- name: Extract package and semver from tag
|
||||
if: ${{ github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag' }}
|
||||
if: ${{ github.ref_type == 'tag' }}
|
||||
id: extract-tag
|
||||
uses: ./packages/actions/src/formatTag
|
||||
with:
|
||||
tag: ${{ env.BRANCH_NAME }}
|
||||
tag: ${{ env.GITHUB_REF_NAME }}
|
||||
|
||||
- name: Move docs to correct directory
|
||||
if: ${{ (github.event.inputs.ref || env.BRANCH_OR_TAG == 'tag') && matrix.package == steps.extract-tag.outputs.package }}
|
||||
if: ${{ github.ref_type == 'tag' && matrix.package == steps.extract-tag.outputs.package }}
|
||||
env:
|
||||
PACKAGE: ${{ steps.extract-tag.outputs.package }}
|
||||
SEMVER: ${{ steps.extract-tag.outputs.semver }}
|
||||
run: |
|
||||
mkdir -p out/${PACKAGE}
|
||||
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${SEMVER}.json
|
||||
if [[ $PACKAGE == "discord.js" ]]; then
|
||||
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${SEMVER}.json
|
||||
fi
|
||||
if [[ $PACKAGE != "discord.js" ]]; then
|
||||
mv docs/${PACKAGE}/docs/docs.api.json out/${PACKAGE}/${SEMVER}.api.json
|
||||
fi
|
||||
|
||||
- name: Move docs to correct directory
|
||||
if: ${{ !github.event.inputs.ref && env.BRANCH_OR_TAG == 'branch' }}
|
||||
if: ${{ github.ref_type == 'branch' }}
|
||||
env:
|
||||
PACKAGE: ${{ matrix.package }}
|
||||
run: |
|
||||
mkdir -p out/${PACKAGE}
|
||||
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${BRANCH_NAME}.json
|
||||
if [[ $PACKAGE == "discord.js" ]]; then
|
||||
mv docs/${PACKAGE}/docs/docs.json out/${PACKAGE}/${GITHUB_REF_NAME}.json
|
||||
fi
|
||||
if [[ $PACKAGE != "discord.js" ]]; then
|
||||
mv docs/${PACKAGE}/docs/docs.api.json out/${PACKAGE}/${GITHUB_REF_NAME}.api.json
|
||||
fi
|
||||
|
||||
- name: Commit and push
|
||||
run: |
|
||||
@@ -144,5 +146,5 @@ jobs:
|
||||
git config user.name github-actions[bot]
|
||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||
git add .
|
||||
git commit -m "Docs build for ${BRANCH_OR_TAG} ${BRANCH_NAME}: ${SHA}" || true
|
||||
git commit -m "Docs build for ${GITHUB_REF_TYPE} ${GITHUB_REF_NAME}: ${GITHUB_SHA}" || true
|
||||
git push
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Label Sync
|
||||
name: Label sync
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
@@ -9,14 +9,15 @@ on:
|
||||
paths:
|
||||
- '.github/labels.yml'
|
||||
jobs:
|
||||
labelsync:
|
||||
label-sync:
|
||||
name: Label sync
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Label sync
|
||||
uses: crazy-max/ghaction-github-labeler@v3
|
||||
uses: crazy-max/ghaction-github-labeler@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,28 +1,26 @@
|
||||
name: npm auto deprecate
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 1 * * *'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
auto-deprecate:
|
||||
npm-auto-deprecate:
|
||||
name: npm auto deprecate
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
uses: ./packages/actions/src/yarnCache
|
||||
|
||||
- name: Deprecate versions
|
||||
run: 'yarn npm-deprecate --name "*dev*" --package @discordjs/builders @discordjs/collection discord.js @discordjs/rest @discordjs/voice'
|
||||
run: 'yarn npm-deprecate --name "*dev*" --package @discordjs/brokers @discordjs/builders @discordjs/collection @discordjs/core discord.js @discordjs/proxy @discordjs/rest @discordjs/util @discordjs/voice @discordjs/ws'
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
@@ -1,16 +1,17 @@
|
||||
name: 'PR Automation'
|
||||
name: 'PR Triage'
|
||||
on:
|
||||
pull_request_target:
|
||||
jobs:
|
||||
triage:
|
||||
pr-triage:
|
||||
name: PR Triage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Automatically label PR
|
||||
uses: actions/labeler@v3
|
||||
uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
sync-labels: true
|
||||
|
||||
- name: Automatically assign reviewers
|
||||
if: github.event.action == 'opened'
|
||||
uses: kentaro-m/auto-assign-action@v1.2.1
|
||||
uses: kentaro-m/auto-assign-action@v1.2.3
|
||||
25
.github/workflows/publish-dev-docker.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Publish dev docker images
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
docker-publish:
|
||||
name: Docker publish
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
run: echo ${{ secrets.DOCKER_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
|
||||
|
||||
- name: Build the image
|
||||
run: docker build -t discordjs/proxy:latest -f packages/proxy-container/Dockerfile .
|
||||
|
||||
- name: Push image to DockerHub
|
||||
run: docker push discordjs/proxy:latest
|
||||
56
.github/workflows/publish-dev.yml
vendored
@@ -1,75 +1,59 @@
|
||||
name: Publish dev
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 */12 * * *'
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
npm:
|
||||
name: npm
|
||||
npm-publish:
|
||||
name: npm publish
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- package: '@discordjs/brokers'
|
||||
folder: 'brokers'
|
||||
- package: '@discordjs/builders'
|
||||
folder: 'builders'
|
||||
- package: '@discordjs/collection'
|
||||
folder: 'collection'
|
||||
- package: '@discordjs/core'
|
||||
folder: 'core'
|
||||
- package: 'discord.js'
|
||||
folder: 'discord.js'
|
||||
- package: '@discordjs/proxy'
|
||||
folder: 'proxy'
|
||||
- package: '@discordjs/rest'
|
||||
folder: 'rest'
|
||||
- package: '@discordjs/util'
|
||||
folder: 'util'
|
||||
- package: '@discordjs/voice'
|
||||
folder: 'voice'
|
||||
- package: '@discordjs/ws'
|
||||
folder: 'ws'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
if: github.repository_owner == 'discordjs'
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: https://registry.npmjs.org/
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: yarn.lock
|
||||
|
||||
- name: Turbo cache
|
||||
id: turbo-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
turbo-${{ github.job }}-${{ github.ref_name }}-
|
||||
|
||||
- name: Check previous released version
|
||||
id: pre-release
|
||||
run: |
|
||||
if [[ $(npm view ${{ matrix.package }}@dev version | grep -e "$(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json)\..*-$(git rev-parse --short HEAD)") ]]; \
|
||||
then echo '::set-output name=release::false'; \
|
||||
else echo '::set-output name=release::true'; fi
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.pre-release.outputs.release == 'true'
|
||||
run: yarn --immutable
|
||||
uses: ./packages/actions/src/yarnCache
|
||||
|
||||
- name: Build dependencies
|
||||
if: steps.pre-release.outputs.release == 'true'
|
||||
run: yarn build --cache-dir=".turbo"
|
||||
run: yarn build
|
||||
|
||||
- name: Deprecate old versions
|
||||
if: steps.pre-release.outputs.release == 'true'
|
||||
run: npm deprecate ${{ matrix.package }}@"~$(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json)" "no longer supported" || true
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
|
||||
- name: Publish
|
||||
if: steps.pre-release.outputs.release == 'true'
|
||||
- name: Publish package
|
||||
run: |
|
||||
yarn workspace ${{ matrix.package }} version $(jq --raw-output '.version' packages/${{ matrix.folder }}/package.json).$(date +%s)-$(git rev-parse --short HEAD)
|
||||
yarn workspace ${{ matrix.package }} release --preid "dev.$(date +%s)-$(git rev-parse --short HEAD)"
|
||||
yarn workspace ${{ matrix.package }} npm publish --tag dev || true
|
||||
env:
|
||||
YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
|
||||
|
||||
25
.github/workflows/publish-docker.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Publish docker images
|
||||
on:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
docker-publish:
|
||||
name: Docker publish
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to DockerHub
|
||||
run: echo ${{ secrets.DOCKER_ACCESS_TOKEN }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
|
||||
|
||||
- name: Build docker image
|
||||
run: docker build -t discordjs/proxy:latest -f packages/proxy-container/Dockerfile .
|
||||
|
||||
- name: Tag image with major
|
||||
run: docker tag discordjs/proxy discordjs/proxy:$(cut -d '.' -f1 <<< $(jq --raw-output '.version' packages/proxy-container/package.json))
|
||||
|
||||
- name: Push image to DockerHub
|
||||
run: docker push --all-tags discordjs/proxy
|
||||
37
.github/workflows/test.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: yarn.lock
|
||||
|
||||
- name: Turbo cache
|
||||
id: turbo-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .turbo
|
||||
key: turbo-${{ github.job }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
turbo-${{ github.job }}-${{ github.ref_name }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
||||
- name: ESLint
|
||||
run: yarn lint --cache-dir=".turbo"
|
||||
|
||||
- name: Tests
|
||||
run: yarn test
|
||||
|
||||
- name: Build
|
||||
run: yarn build --cache-dir=".turbo"
|
||||
63
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Tests
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
tests:
|
||||
name: Tests
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install node.js v16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./packages/actions/src/yarnCache
|
||||
|
||||
- name: Build dependencies (PR)
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
run: yarn build --filter="...[origin/${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || 'main' }}]"
|
||||
|
||||
- name: Build dependencies (Push)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: yarn build --filter="...[HEAD^1]"
|
||||
|
||||
- name: ESLint (PR)
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
run: yarn lint --filter="...[origin/${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || 'main' }}]" -- --format=compact
|
||||
|
||||
- name: ESLint (Push)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: yarn lint --filter="...[HEAD^1]" -- --format=compact
|
||||
|
||||
- name: Tests (PR)
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
run: yarn test --filter="...[origin/${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || 'main' }}]"
|
||||
|
||||
- name: Tests (Push)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: yarn test --filter="...[HEAD^1]"
|
||||
|
||||
- name: Docs (PR)
|
||||
if: ${{ github.event_name != 'push' }}
|
||||
run: yarn docs --filter="...[origin/${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref || 'main' }}]"
|
||||
|
||||
- name: Docs (Push)
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: yarn docs --filter="...[HEAD^1]"
|
||||
|
||||
- name: Upload Coverage
|
||||
if: github.repository_owner == 'discordjs'
|
||||
uses: ./packages/actions/src/uploadCoverage
|
||||
5
.gitignore
vendored
@@ -27,6 +27,7 @@ dist/
|
||||
.turbo
|
||||
tsconfig.tsbuildinfo
|
||||
coverage/
|
||||
out/
|
||||
|
||||
# yarn
|
||||
.pnp.*
|
||||
@@ -36,3 +37,7 @@ coverage/
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
# Cache
|
||||
.prettiercache
|
||||
.eslintcache
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn format
|
||||
yarn build:affected && yarn lint-staged
|
||||
|
||||
5
.lintstagedrc.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"*": "prettier --ignore-unknown --write",
|
||||
"{src/**,__tests__/**}.{mjs,js,cjs,ts,tsx,astro}": "eslint --ext .mjs,.js,.cjs,.ts,.tsx,.astro --fix",
|
||||
"src/**.ts": "vitest related --run --config ../../vitest.config.ts"
|
||||
}
|
||||
5
.vscode/extensions.json
vendored
@@ -7,6 +7,9 @@
|
||||
"codezombiech.gitignore",
|
||||
"eamodio.gitlens",
|
||||
"christian-kohler.npm-intellisense",
|
||||
"christian-kohler.path-intellisense"
|
||||
"christian-kohler.path-intellisense",
|
||||
"antfu.unocss",
|
||||
"astro-build.astro-vscode",
|
||||
"unifiedjs.vscode-mdx"
|
||||
]
|
||||
}
|
||||
|
||||
15
.vscode/settings.json
vendored
@@ -1,12 +1,19 @@
|
||||
{
|
||||
"eslint.workingDirectories": [{ "pattern": "./packages/*" }],
|
||||
"eslint.workingDirectories": [{ "pattern": "./apps/*" }, { "pattern": "./packages/*" }],
|
||||
"eslint.validate": ["javascript", "javascriptreact", "astro", "typescript", "typescriptreact"],
|
||||
"prettier.documentSelectors": ["**/*.astro"],
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true,
|
||||
"source.organizeImports": false
|
||||
},
|
||||
"files.exclude": {
|
||||
"**/node_modules": true
|
||||
}
|
||||
"editor.trimAutoWhitespace": false,
|
||||
"files.associations": {
|
||||
"*.mdx": "markdown"
|
||||
},
|
||||
"files.insertFinalNewline": true,
|
||||
"files.eol": "\n",
|
||||
"npm.packageManager": "yarn",
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
diff --git a/lib/TSDocConfigFile.js b/lib/TSDocConfigFile.js
|
||||
index caf3515d60fd386c5909db5a0aa8b4180b10d602..6fa4f1984b6ba6b3a7aecd05e54477ebf141af94 100644
|
||||
--- a/lib/TSDocConfigFile.js
|
||||
+++ b/lib/TSDocConfigFile.js
|
||||
@@ -31,8 +31,7 @@ const ajv_1 = __importDefault(require("ajv"));
|
||||
const jju = __importStar(require("jju"));
|
||||
const ajv = new ajv_1.default({ verbose: true });
|
||||
function initializeSchemaValidator() {
|
||||
- const jsonSchemaPath = resolve.sync('@microsoft/tsdoc/schemas/tsdoc.schema.json', { basedir: __dirname });
|
||||
- const jsonSchemaContent = fs.readFileSync(jsonSchemaPath).toString();
|
||||
+ const jsonSchemaContent = "{\"title\":\"TSDoc Configuration\",\"description\":\"Describes the TSDoc configuration for a TypeScript project\",\"type\":\"object\",\"properties\":{\"$schema\":{\"description\":\"Part of the JSON Schema standard, this optional keyword declares the URL of the schema that the file conforms to. Editors may download the schema and use it to perform syntax highlighting.\",\"type\":\"string\"},\"extends\":{\"description\":\"Optionally specifies one or more JSON config files that will be combined with this file. This provides a way for standard settings to be shared across multiple projects. Important: The \\\"extends\\\" paths are resolved using NodeJS module resolution, so a path to a local file MUST be prefixed with \\\"./\\\".\",\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"noStandardTags\":{\"description\":\"By default, the config file loader will predefine all of the standardized TSDoc tags. To disable this and start with a completely empty configuration, set \\\"noStandardTags\\\"=true.\",\"type\":\"boolean\"},\"tagDefinitions\":{\"description\":\"Additional tags to support when parsing documentation comments with TSDoc.\",\"type\":\"array\",\"items\":{\"$ref\":\"#/definitions/tsdocTagDefinition\"}},\"supportedHtmlElements\":{\"description\":\"The HTML element names that are supported in this configuration. Used in conjunction with the \\\"reportUnsupportedHtmlElements\\\" setting.\",\"type\":\"array\",\"items\":{\"type\":\"string\",\"pattern\":\"^[a-zA-Z0-9-]+$\"}},\"reportUnsupportedHtmlElements\":{\"description\":\"Whether an error should be reported when an unsupported HTML element is encountered in a doc comment. Defaults to \\\"true\\\" if the \\\"supportedHtmlElements\\\" field is present in this file, \\\"false\\\" if not.\",\"type\":\"boolean\"},\"supportForTags\":{\"description\":\"A collection of key/value pairs. The key is a TSDoc tag name (e.g. \\\"@myTag\\\") that must be defined in this configuration. The value is a boolean indicating whether the tag is supported. The TSDoc parser may report warnings when unsupported tags are encountered. If \\\"supportForTags\\\" is specified for at least one tag, then the \\\"reportUnsupportedTags\\\" validation check is enabled by default.\",\"type\":\"object\",\"patternProperties\":{\"@[a-zA-Z][a-zA-Z0-9]*$\":{\"type\":\"boolean\"}},\"additionalItems\":false}},\"required\":[\"$schema\"],\"additionalProperties\":false,\"definitions\":{\"tsdocTagDefinition\":{\"description\":\"Configuration for a custom supported TSDoc tag.\",\"type\":\"object\",\"properties\":{\"tagName\":{\"description\":\"Name of the custom tag. TSDoc tag names start with an at-sign (@) followed by ASCII letters using camelCase capitalization.\",\"type\":\"string\"},\"syntaxKind\":{\"description\":\"Syntax kind of the custom tag. \\\"inline\\\" means that this tag can appear inside other documentation sections (example: {@link}). \\\"block\\\" means that this tag starts a new documentation section (example: @remarks). \\\"modifier\\\" means that this tag's presence indicates an aspect of the associated API item (example: @internal).\",\"type\":\"string\",\"enum\":[\"inline\",\"block\",\"modifier\"]},\"allowMultiple\":{\"description\":\"If true, then this tag may appear multiple times in a doc comment. By default, a tag may only appear once.\",\"type\":\"boolean\"}},\"required\":[\"tagName\",\"syntaxKind\"],\"additionalProperties\":false}}}";
|
||||
const jsonSchema = jju.parse(jsonSchemaContent, { mode: 'cjson' });
|
||||
return ajv.compile(jsonSchema);
|
||||
}
|
||||
338
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
vendored
6
.yarn/plugins/@yarnpkg/plugin-version.cjs
vendored
786
.yarn/releases/yarn-3.2.1.cjs
vendored
801
.yarn/releases/yarn-3.2.4.cjs
vendored
Normal file
@@ -8,4 +8,4 @@ plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
|
||||
spec: "@yarnpkg/plugin-version"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-3.2.4.cjs
|
||||
|
||||
191
LICENSE
Normal file
@@ -0,0 +1,191 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Copyright 2021 Noel Buechler
|
||||
Copyright 2015 Amish Shah
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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.
|
||||
86
README.md
@@ -1,15 +1,19 @@
|
||||
<div align="center">
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
|
||||
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/v/discord.js.svg?maxAge=3600" alt="npm version" /></a>
|
||||
<a href="https://www.npmjs.com/package/discord.js"><img src="https://img.shields.io/npm/dt/discord.js.svg?maxAge=3600" alt="npm downloads" /></a>
|
||||
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Tests status" /></a>
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
|
||||
<a href="https://www.npmjs.com/package/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>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## About
|
||||
@@ -42,19 +46,18 @@ pnpm add discord.js
|
||||
|
||||
## Example usage
|
||||
|
||||
Install all required dependencies:
|
||||
Install discord.js:
|
||||
|
||||
```sh-session
|
||||
npm install discord.js @discordjs/rest discord-api-types
|
||||
yarn add discord.js @discordjs/rest discord-api-types
|
||||
pnpm add discord.js @discordjs/rest discord-api-types
|
||||
npm install discord.js
|
||||
yarn add discord.js
|
||||
pnpm add discord.js
|
||||
```
|
||||
|
||||
Register a slash command against the Discord API:
|
||||
|
||||
```js
|
||||
const { REST } = require('@discordjs/rest');
|
||||
const { Routes } = require('discord-api-types/v10');
|
||||
const { REST, Routes } = require('discord.js');
|
||||
|
||||
const commands = [
|
||||
{
|
||||
@@ -63,13 +66,13 @@ const commands = [
|
||||
},
|
||||
];
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken('token');
|
||||
const rest = new REST({ version: '10' }).setToken(TOKEN);
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
console.log('Started refreshing application (/) commands.');
|
||||
|
||||
await rest.put(Routes.applicationGuildCommands(CLIENT_ID, GUILD_ID), { body: commands });
|
||||
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
|
||||
|
||||
console.log('Successfully reloaded application (/) commands.');
|
||||
} catch (error) {
|
||||
@@ -89,39 +92,54 @@ client.on('ready', () => {
|
||||
});
|
||||
|
||||
client.on('interactionCreate', async (interaction) => {
|
||||
if (!interaction.isCommand()) return;
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
|
||||
if (interaction.commandName === 'ping') {
|
||||
await interaction.reply('Pong!');
|
||||
}
|
||||
});
|
||||
|
||||
client.login('token');
|
||||
client.login(TOKEN);
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
|
||||
- [Documentation](https://discord.js.org/#/docs)
|
||||
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
|
||||
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v13.html), including updated and removed items in the library.
|
||||
- [discord.js Discord server](https://discord.gg/djs)
|
||||
- [Discord API Discord server](https://discord.gg/discord-api)
|
||||
- [GitHub](https://github.com/discordjs/discord.js)
|
||||
- [npm](https://www.npmjs.com/package/discord.js)
|
||||
- [Related libraries](https://discord.com/developers/docs/topics/community-resources#libraries)
|
||||
- [Website][website] ([source][website-source])
|
||||
- [Documentation][documentation]
|
||||
- [Guide][guide] ([source][guide-source])
|
||||
See also the [Update Guide][guide-update], including updated and removed items in the library.
|
||||
- [discord.js Discord server][discord]
|
||||
- [Discord API Discord server][discord-api]
|
||||
- [GitHub][source]
|
||||
- [npm][npm]
|
||||
- [Related libraries][related-libs]
|
||||
|
||||
### Extensions
|
||||
|
||||
- [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
|
||||
- [RPC][rpc] ([source][rpc-source])
|
||||
|
||||
## Contributing
|
||||
|
||||
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
|
||||
[documentation](https://discord.js.org/#/docs).
|
||||
See [the contribution guide](https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md) if you'd like to submit a PR.
|
||||
[documentation][documentation].
|
||||
See [the contribution guide][contributing] if you'd like to submit a PR.
|
||||
|
||||
## Help
|
||||
|
||||
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
|
||||
nudge in the right direction, please don't hesitate to join our official [discord.js Server](https://discord.gg/djs).
|
||||
nudge in the right direction, please don't hesitate to join our official [discord.js Server][discord].
|
||||
|
||||
[website]: https://discord.js.org/
|
||||
[website-source]: https://github.com/discordjs/discord.js/tree/main/apps/website
|
||||
[documentation]: https://discord.js.org/#/docs
|
||||
[guide]: https://discordjs.guide/
|
||||
[guide-source]: https://github.com/discordjs/guide
|
||||
[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/packages/discord.js
|
||||
[npm]: https://www.npmjs.com/package/discord.js
|
||||
[related-libs]: https://discord.com/developers/docs/topics/community-resources#libraries
|
||||
[rpc]: https://www.npmjs.com/package/discord-rpc
|
||||
[rpc-source]: https://github.com/discordjs/RPC
|
||||
[contributing]: https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md
|
||||
|
||||
382
api-extractor.json
Normal file
@@ -0,0 +1,382 @@
|
||||
/**
|
||||
* Config file for API Extractor. For more info, please visit: https://api-extractor.com
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
|
||||
/**
|
||||
* Optionally specifies another JSON config file that this file extends from. This provides a way for
|
||||
* standard settings to be shared across multiple projects.
|
||||
*
|
||||
* If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains
|
||||
* the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be
|
||||
* resolved using NodeJS require().
|
||||
*
|
||||
* SUPPORTED TOKENS: none
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "extends": "./shared/api-extractor-base.json"
|
||||
// "extends": "my-package/include/api-extractor-base.json"
|
||||
|
||||
/**
|
||||
* Determines the "<projectFolder>" token that can be used with other config file settings. The project folder
|
||||
* typically contains the tsconfig.json and package.json config files, but the path is user-defined.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting.
|
||||
*
|
||||
* The default value for "projectFolder" is the token "<lookup>", which means the folder is determined by traversing
|
||||
* parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder
|
||||
* that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error
|
||||
* will be reported.
|
||||
*
|
||||
* SUPPORTED TOKENS: <lookup>
|
||||
* DEFAULT VALUE: "<lookup>"
|
||||
*/
|
||||
// "projectFolder": "..",
|
||||
|
||||
/**
|
||||
* (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor
|
||||
* analyzes the symbols exported by this module.
|
||||
*
|
||||
* The file extension must be ".d.ts" and not ".ts".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
*/
|
||||
"mainEntryPointFilePath": "<projectFolder>/dist/index.d.ts",
|
||||
|
||||
/**
|
||||
* A list of NPM package names whose exports should be treated as part of this package.
|
||||
*
|
||||
* For example, suppose that Webpack is used to generate a distributed bundle for the project "library1",
|
||||
* and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part
|
||||
* of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly
|
||||
* imports library2. To avoid this, we can specify:
|
||||
*
|
||||
* "bundledPackages": [ "library2" ],
|
||||
*
|
||||
* This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been
|
||||
* local files for library1.
|
||||
*/
|
||||
"bundledPackages": [],
|
||||
|
||||
/**
|
||||
* Determines how the TypeScript compiler engine will be invoked by API Extractor.
|
||||
*/
|
||||
"compiler": {
|
||||
/**
|
||||
* Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* Note: This setting will be ignored if "overrideTsconfig" is used.
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/tsconfig.json"
|
||||
*/
|
||||
// "tsconfigFilePath": "<projectFolder>/tsconfig.json",
|
||||
/**
|
||||
* Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk.
|
||||
* The object must conform to the TypeScript tsconfig schema:
|
||||
*
|
||||
* http://json.schemastore.org/tsconfig
|
||||
*
|
||||
* If omitted, then the tsconfig.json file will be read from the "projectFolder".
|
||||
*
|
||||
* DEFAULT VALUE: no overrideTsconfig section
|
||||
*/
|
||||
// "overrideTsconfig": {
|
||||
// . . .
|
||||
// }
|
||||
/**
|
||||
* This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended
|
||||
* and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when
|
||||
* dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses
|
||||
* for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "skipLibCheck": true,
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the API report file (*.api.md) will be generated.
|
||||
*/
|
||||
"apiReport": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate an API report.
|
||||
*/
|
||||
"enabled": false
|
||||
|
||||
/**
|
||||
* The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce
|
||||
* a full file path.
|
||||
*
|
||||
* The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/".
|
||||
*
|
||||
* SUPPORTED TOKENS: <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<unscopedPackageName>.api.md"
|
||||
*/
|
||||
// "reportFileName": "<unscopedPackageName>.api.md",
|
||||
|
||||
/**
|
||||
* Specifies the folder where the API report file is written. The file name portion is determined by
|
||||
* the "reportFileName" setting.
|
||||
*
|
||||
* The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy,
|
||||
* e.g. for an API review.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/"
|
||||
*/
|
||||
// "reportFolder": "<projectFolder>/temp/",
|
||||
|
||||
/**
|
||||
* Specifies the folder where the temporary report file is written. The file name portion is determined by
|
||||
* the "reportFileName" setting.
|
||||
*
|
||||
* After the temporary file is written to disk, it is compared with the file in the "reportFolder".
|
||||
* If they are different, a production build will fail.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/"
|
||||
*/
|
||||
// "reportTempFolder": "<projectFolder>/temp/"
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the doc model file (*.api.json) will be generated.
|
||||
*/
|
||||
"docModel": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate a doc model file.
|
||||
*/
|
||||
"enabled": true,
|
||||
|
||||
/**
|
||||
* The output path for the doc model file. The file extension should be ".api.json".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/temp/<unscopedPackageName>.api.json"
|
||||
*/
|
||||
"apiJsonFilePath": "<projectFolder>/docs/docs.api.json"
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the .d.ts rollup file will be generated.
|
||||
*/
|
||||
"dtsRollup": {
|
||||
/**
|
||||
* (REQUIRED) Whether to generate the .d.ts rollup file.
|
||||
*/
|
||||
"enabled": false
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated without any trimming.
|
||||
* This file will include all declarations that are exported by the main entry point.
|
||||
*
|
||||
* If the path is an empty string, then this file will not be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<projectFolder>/dist/<unscopedPackageName>.d.ts"
|
||||
*/
|
||||
// "untrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release.
|
||||
* This file will include only declarations that are marked as "@public", "@beta", or "@alpha".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "alphaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-alpha.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release.
|
||||
* This file will include only declarations that are marked as "@public" or "@beta".
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "betaTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-beta.d.ts",
|
||||
|
||||
/**
|
||||
* Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release.
|
||||
* This file will include only declarations that are marked as "@public".
|
||||
*
|
||||
* If the path is an empty string, then this file will not be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: ""
|
||||
*/
|
||||
// "publicTrimmedFilePath": "<projectFolder>/dist/<unscopedPackageName>-public.d.ts",
|
||||
|
||||
/**
|
||||
* When a declaration is trimmed, by default it will be replaced by a code comment such as
|
||||
* "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the
|
||||
* declaration completely.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "omitTrimmingComments": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures how the tsdoc-metadata.json file will be generated.
|
||||
*/
|
||||
"tsdocMetadata": {
|
||||
/**
|
||||
* Whether to generate the tsdoc-metadata.json file.
|
||||
*
|
||||
* DEFAULT VALUE: true
|
||||
*/
|
||||
// "enabled": true,
|
||||
/**
|
||||
* Specifies where the TSDoc metadata file should be written.
|
||||
*
|
||||
* The path is resolved relative to the folder of the config file that contains the setting; to change this,
|
||||
* prepend a folder token such as "<projectFolder>".
|
||||
*
|
||||
* The default value is "<lookup>", which causes the path to be automatically inferred from the "tsdocMetadata",
|
||||
* "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup
|
||||
* falls back to "tsdoc-metadata.json" in the package folder.
|
||||
*
|
||||
* SUPPORTED TOKENS: <projectFolder>, <packageName>, <unscopedPackageName>
|
||||
* DEFAULT VALUE: "<lookup>"
|
||||
*/
|
||||
// "tsdocMetadataFilePath": "<projectFolder>/dist/tsdoc-metadata.json"
|
||||
},
|
||||
|
||||
/**
|
||||
* Specifies what type of newlines API Extractor should use when writing output files. By default, the output files
|
||||
* will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead.
|
||||
* To use the OS's default newline kind, specify "os".
|
||||
*
|
||||
* DEFAULT VALUE: "crlf"
|
||||
*/
|
||||
"newlineKind": "lf",
|
||||
|
||||
/**
|
||||
* Configures how API Extractor reports error and warning messages produced during analysis.
|
||||
*
|
||||
* There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages.
|
||||
*/
|
||||
"messages": {
|
||||
/**
|
||||
* Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing
|
||||
* the input .d.ts files.
|
||||
*
|
||||
* TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551"
|
||||
*
|
||||
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
|
||||
*/
|
||||
"compilerMessageReporting": {
|
||||
/**
|
||||
* Configures the default routing for messages that don't match an explicit rule in this table.
|
||||
*/
|
||||
"default": {
|
||||
/**
|
||||
* Specifies whether the message should be written to the the tool's output log. Note that
|
||||
* the "addToApiReportFile" property may supersede this option.
|
||||
*
|
||||
* Possible values: "error", "warning", "none"
|
||||
*
|
||||
* Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail
|
||||
* and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes
|
||||
* the "--local" option), the warning is displayed but the build will not fail.
|
||||
*
|
||||
* DEFAULT VALUE: "warning"
|
||||
*/
|
||||
"logLevel": "warning"
|
||||
|
||||
/**
|
||||
* When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md),
|
||||
* then the message will be written inside that file; otherwise, the message is instead logged according to
|
||||
* the "logLevel" option.
|
||||
*
|
||||
* DEFAULT VALUE: false
|
||||
*/
|
||||
// "addToApiReportFile": false
|
||||
}
|
||||
|
||||
// "TS2551": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures handling of messages reported by API Extractor during its analysis.
|
||||
*
|
||||
* API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag"
|
||||
*
|
||||
* DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings
|
||||
*/
|
||||
"extractorMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
// "addToApiReportFile": false
|
||||
},
|
||||
|
||||
// Disable the following warning:
|
||||
// (ae-missing-release-tag) "x" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
"ae-missing-release-tag": {
|
||||
"logLevel": "none"
|
||||
}
|
||||
|
||||
// "ae-extra-release-tag": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
},
|
||||
|
||||
/**
|
||||
* Configures handling of messages reported by the TSDoc parser when analyzing code comments.
|
||||
*
|
||||
* TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text"
|
||||
*
|
||||
* DEFAULT VALUE: A single "default" entry with logLevel=warning.
|
||||
*/
|
||||
"tsdocMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
// "addToApiReportFile": false
|
||||
}
|
||||
|
||||
// "tsdoc-link-tag-unescaped-text": {
|
||||
// "logLevel": "warning",
|
||||
// "addToApiReportFile": true
|
||||
// },
|
||||
//
|
||||
// . . .
|
||||
}
|
||||
}
|
||||
}
|
||||
11
apps/guide/.eslintrc.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json", "neon/react", "neon/astro", "neon/prettier"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"react/jsx-filename-extension": [1, { "extensions": [".tsx", ".astro"] }]
|
||||
}
|
||||
}
|
||||
30
apps/guide/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Packages
|
||||
node_modules/
|
||||
|
||||
# Log files
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Env
|
||||
.env
|
||||
|
||||
# Dist
|
||||
dist/
|
||||
typings/
|
||||
.cache/
|
||||
build/
|
||||
api/
|
||||
src/styles/unocss.css
|
||||
.next/
|
||||
|
||||
# Miscellaneous
|
||||
.tmp/
|
||||
coverage/
|
||||
.vercel
|
||||
public/searchIndex
|
||||
1
apps/guide/.lintstagedrc.cjs
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('../../.lintstagedrc.json');
|
||||
15
apps/guide/.prettierignore
Normal file
@@ -0,0 +1,15 @@
|
||||
# Autogenerated
|
||||
CHANGELOG.md
|
||||
.turbo
|
||||
dist/
|
||||
docs/**/*
|
||||
!docs/index.yml
|
||||
!docs/README.md
|
||||
coverage/
|
||||
.cache
|
||||
build/
|
||||
src/styles/unocss.css
|
||||
api/
|
||||
.next/
|
||||
.vercel/
|
||||
.cache/
|
||||
8
apps/guide/.prettierrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
...require('../../.prettierrc.json'),
|
||||
plugins: [
|
||||
'prettier-plugin-astro',
|
||||
'prettier-plugin-tailwindcss', // MUST come last
|
||||
],
|
||||
pluginSearchDirs: false,
|
||||
};
|
||||
46
apps/guide/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
<div align="center">
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.js.org"><img src="https://discord.js.org/static/logo.svg" width="546" alt="discord.js" /></a>
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
<a href="https://discord.gg/djs"><img src="https://img.shields.io/discord/222078108977594368?color=5865F2&logo=discord&logoColor=white" alt="Discord server" /></a>
|
||||
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/actions/workflows/test.yml/badge.svg" alt="Build status" /></a>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"><img src="https://raw.githubusercontent.com/discordjs/discord.js/main/.github/powered-by-vercel.svg" alt="Vercel" /></a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## Links
|
||||
|
||||
- [Website][website] ([source][website-source])
|
||||
- [Documentation][documentation]
|
||||
- [Guide][guide] ([source][guide-source])
|
||||
See also the [Update Guide][guide-update], including updated and removed items in the library.
|
||||
- [discord.js Discord server][discord]
|
||||
- [Discord API Discord server][discord-api]
|
||||
- [GitHub][source]
|
||||
- [Related libraries][related-libs]
|
||||
|
||||
## Contributing
|
||||
|
||||
See [the contribution guide][contributing] if you'd like to submit a PR.
|
||||
|
||||
## Help
|
||||
|
||||
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
|
||||
nudge in the right direction, please don't hesitate to join our official [discord.js Server][discord].
|
||||
|
||||
[website]: https://discord.js.org/
|
||||
[website-source]: https://github.com/discordjs/discord.js/tree/main/apps/website
|
||||
[documentation]: https://discord.js.org/
|
||||
[guide]: https://discordjs.guide/
|
||||
[guide-source]: https://github.com/discordjs/guide
|
||||
[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
|
||||
[related-libs]: https://discord.com/developers/docs/topics/community-resources#libraries
|
||||
[contributing]: https://github.com/discordjs/discord.js/blob/main/.github/CONTRIBUTING.md
|
||||
117
apps/guide/astro.config.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { fileURLToPath, URL } from 'node:url';
|
||||
import image from '@astrojs/image';
|
||||
import mdx from '@astrojs/mdx';
|
||||
import prefetch from '@astrojs/prefetch';
|
||||
import react from '@astrojs/react';
|
||||
import { remarkCodeHike } from '@code-hike/mdx';
|
||||
import { defineConfig } from 'astro/config';
|
||||
import compress from 'astro-compress';
|
||||
import critters from 'astro-critters';
|
||||
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 shikiThemeDarkPlus from 'shiki/themes/dark-plus.json' assert { type: 'json' };
|
||||
import Unocss from 'unocss/astro';
|
||||
|
||||
const LinkIcon = h(
|
||||
'svg',
|
||||
{
|
||||
width: '1rem',
|
||||
height: '1rem',
|
||||
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: string) => {
|
||||
const node = h('span.sr-only', `Section titled ${escape(text)}`);
|
||||
node.properties!['is:raw'] = true;
|
||||
return node;
|
||||
};
|
||||
|
||||
const rootDir = new URL('../../', import.meta.url);
|
||||
|
||||
export default defineConfig({
|
||||
integrations: [
|
||||
react(),
|
||||
mdx({
|
||||
remarkPlugins: [[remarkCodeHike, { autoImport: false, theme: shikiThemeDarkPlus, lineNumbers: true }]],
|
||||
rehypePlugins: [
|
||||
rehypeSlug,
|
||||
[
|
||||
rehypeAutolinkHeadings,
|
||||
{
|
||||
properties: {
|
||||
class:
|
||||
'relative inline-flex w-6 h-6 place-items-center place-content-center outline-0 text-black dark:text-white ml-2',
|
||||
},
|
||||
behavior: 'after',
|
||||
group: ({ tagName }: { tagName: string }) =>
|
||||
h('div', {
|
||||
class: `[&>*]:inline-block [&>h1]:m-0 [&>h2]:m-0 [&>h3]:m-0 [&>h4]:m-0 level-${tagName}`,
|
||||
tabIndex: -1,
|
||||
}),
|
||||
content: (heading: Node) => [
|
||||
h(
|
||||
`span.anchor-icon`,
|
||||
{
|
||||
ariaHidden: 'true',
|
||||
},
|
||||
LinkIcon,
|
||||
),
|
||||
createSROnlyLabel(toString(heading)),
|
||||
],
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
image({
|
||||
serviceEntryPoint: '@astrojs/image/sharp',
|
||||
}),
|
||||
prefetch({
|
||||
throttle: 3,
|
||||
}),
|
||||
Unocss({
|
||||
configFile: fileURLToPath(new URL('unocss.config.ts', rootDir)),
|
||||
}),
|
||||
critters(),
|
||||
compress(),
|
||||
],
|
||||
markdown: {
|
||||
extendDefaultPlugins: true,
|
||||
syntaxHighlight: false,
|
||||
},
|
||||
vite: {
|
||||
resolve: {
|
||||
alias: {
|
||||
'ariakit/button': fileURLToPath(new URL('node_modules/ariakit/esm/button/index.js', rootDir)),
|
||||
'ariakit/disclosure': fileURLToPath(new URL('node_modules/ariakit/esm/disclosure/index.js', rootDir)),
|
||||
'ariakit/separator': fileURLToPath(new URL('node_modules/ariakit/esm/separator/index.js', rootDir)),
|
||||
'ariakit-utils/dom': fileURLToPath(new URL('node_modules/ariakit-utils/esm/dom.js', rootDir)),
|
||||
'ariakit-utils/events': fileURLToPath(new URL('node_modules/ariakit-utils/esm/events.js', rootDir)),
|
||||
'ariakit-utils/focus': fileURLToPath(new URL('node_modules/ariakit-utils/esm/focus.js', rootDir)),
|
||||
'ariakit-utils/hooks': fileURLToPath(new URL('node_modules/ariakit-utils/esm/hooks.js', rootDir)),
|
||||
'ariakit-utils/misc': fileURLToPath(new URL('node_modules/ariakit-utils/esm/misc.js', rootDir)),
|
||||
'ariakit-utils/platform': fileURLToPath(new URL('node_modules/ariakit-utils/esm/platform.js', rootDir)),
|
||||
'ariakit-utils/system': fileURLToPath(new URL('node_modules/ariakit-utils/esm/system.js', rootDir)),
|
||||
'react-icons/fi': fileURLToPath(new URL('node_modules/react-icons/fi/index.esm.js', rootDir)),
|
||||
'react-icons/vsc': fileURLToPath(new URL('node_modules/react-icons/vsc/index.esm.js', rootDir)),
|
||||
'react-use': fileURLToPath(new URL('node_modules/react-use/esm/index.js', rootDir)),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
89
apps/guide/package.json
Normal file
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"name": "@discordjs/guide",
|
||||
"version": "0.1.0",
|
||||
"description": "Imagine a guide... that explores the many possibilities for your discord.js bot",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "vitest run",
|
||||
"build:local": "yarn build:prod",
|
||||
"build:prod": "yarn workspaces foreach -ptR run build && astro build",
|
||||
"dev": "yarn workspaces foreach -ptR run build && astro dev",
|
||||
"preview": "astro preview",
|
||||
"lint": "prettier --check . && cross-env TIMING=1 eslint src --ext .mjs,.js,.cjs,.ts,.tsx,.astro --format=pretty",
|
||||
"format": "prettier --write . && cross-env TIMING=1 eslint src --ext .mjs,.js,.cjs,.ts,.tsx,.astro --fix --format=pretty",
|
||||
"fmt": "yarn format"
|
||||
},
|
||||
"type": "module",
|
||||
"contributors": [
|
||||
"Crawl <icrawltogo@gmail.com>"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"discord",
|
||||
"api",
|
||||
"bot",
|
||||
"client",
|
||||
"node",
|
||||
"discordapp",
|
||||
"discordjs"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/discordjs/discord.js.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/discordjs/discord.js/issues"
|
||||
},
|
||||
"homepage": "https://discord.js.org",
|
||||
"dependencies": {
|
||||
"@code-hike/mdx": "^0.7.4",
|
||||
"@discordjs/ui": "workspace:^",
|
||||
"ariakit": "^2.0.0-next.41",
|
||||
"react": "^18.2.0",
|
||||
"react-custom-scrollbars-2": "^4.5.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.6.0",
|
||||
"react-use": "^17.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/image": "^0.11.6",
|
||||
"@astrojs/mdx": "^0.12.0",
|
||||
"@astrojs/prefetch": "^0.1.1",
|
||||
"@astrojs/react": "^1.2.2",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/node": "16.18.3",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"@types/react-syntax-highlighter": "^15.5.5",
|
||||
"@unocss/cli": "^0.46.5",
|
||||
"@unocss/reset": "^0.46.5",
|
||||
"@vitejs/plugin-react": "^2.2.0",
|
||||
"@vitest/coverage-c8": "^0.25.3",
|
||||
"astro": "^1.6.11",
|
||||
"astro-compress": "^1.1.12",
|
||||
"astro-critters": "^1.1.12",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-neon": "^0.1.40",
|
||||
"eslint-formatter-pretty": "^4.1.0",
|
||||
"happy-dom": "^7.7.0",
|
||||
"hast-util-to-string": "^2.0.0",
|
||||
"hastscript": "^7.1.0",
|
||||
"html-escaper": "^3.0.3",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-astro": "^0.7.0",
|
||||
"prettier-plugin-tailwindcss": "^0.2.0",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-slug": "^5.1.0",
|
||||
"sharp": "^0.31.2",
|
||||
"shiki": "^0.11.1",
|
||||
"typescript": "^4.9.3",
|
||||
"unocss": "^0.46.5",
|
||||
"vercel": "^28.5.6",
|
||||
"vitest": "^0.25.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
}
|
||||
BIN
apps/guide/public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
apps/guide/public/android-chrome-384x384.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
apps/guide/public/apple-touch-icon-120x120-precomposed.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
apps/guide/public/apple-touch-icon-120x120.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
apps/guide/public/apple-touch-icon-152x152-precomposed.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/guide/public/apple-touch-icon-152x152.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
apps/guide/public/apple-touch-icon-180x180-precomposed.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
apps/guide/public/apple-touch-icon-180x180.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
apps/guide/public/apple-touch-icon-60x60-precomposed.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
apps/guide/public/apple-touch-icon-60x60.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
apps/guide/public/apple-touch-icon-76x76-precomposed.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
apps/guide/public/apple-touch-icon-76x76.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
apps/guide/public/apple-touch-icon-precomposed.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
apps/guide/public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
12
apps/guide/public/browserconfig.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="/mstile-70x70.png"/>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<square310x310logo src="/mstile-310x310.png"/>
|
||||
<wide310x150logo src="/mstile-310x150.png"/>
|
||||
<TileColor>#090a16</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
apps/guide/public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 561 B |
BIN
apps/guide/public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
apps/guide/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
apps/guide/public/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
apps/guide/public/mstile-310x150.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
apps/guide/public/mstile-310x310.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
apps/guide/public/mstile-70x70.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
apps/guide/public/open-graph.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
6
apps/guide/public/powered-by-vercel.svg
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
32
apps/guide/public/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="400.000000pt" height="400.000000pt" viewBox="0 0 400.000000 400.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,400.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 2000 l0 -2000 2000 0 2000 0 0 2000 0 2000 -2000 0 -2000 0 0
|
||||
-2000z m1305 795 c219 -47 373 -197 421 -411 24 -109 16 -315 -16 -399 l-23
|
||||
-61 -59 -11 c-110 -21 -182 -92 -203 -202 -11 -56 -11 -56 -68 -79 -76 -30
|
||||
-201 -42 -464 -42 l-223 0 0 610 0 610 283 0 c210 0 300 -4 352 -15z m890
|
||||
-585 c0 -543 -2 -601 -18 -659 -56 -198 -190 -334 -365 -370 -176 -37 -349 5
|
||||
-471 115 -48 44 -111 134 -111 161 0 6 19 14 43 18 23 4 73 18 110 32 l68 24
|
||||
50 -45 c56 -50 98 -66 175 -66 100 0 207 81 234 178 6 23 10 251 10 625 l0
|
||||
588 138 -3 137 -3 0 -595z m930 570 c93 -29 197 -84 252 -134 l44 -41 -61 -75
|
||||
c-34 -41 -67 -81 -74 -88 -10 -10 -25 -4 -78 32 -95 63 -154 81 -268 81 -79 0
|
||||
-103 -4 -142 -23 -62 -31 -90 -71 -96 -137 -8 -94 28 -137 168 -202 157 -73
|
||||
172 -80 240 -108 236 -97 341 -215 356 -400 16 -193 -82 -363 -258 -449 -91
|
||||
-45 -187 -66 -303 -66 -191 0 -390 74 -524 195 l-40 37 80 93 80 94 73 -53
|
||||
c168 -121 353 -155 491 -92 72 33 108 82 113 155 9 122 -37 162 -323 286 -258
|
||||
111 -350 179 -407 300 -69 148 -37 343 75 463 61 65 195 133 300 152 79 14
|
||||
222 4 302 -20z m-1367 -977 c45 -34 65 -69 70 -125 4 -61 -19 -106 -77 -145
|
||||
-90 -60 -226 3 -238 111 -3 24 -3 56 1 70 8 34 54 86 91 102 40 19 120 12 153
|
||||
-13z"/>
|
||||
<path d="M967 2543 c-4 -3 -7 -159 -7 -346 l0 -339 128 4 c101 3 136 8 172 24
|
||||
106 48 162 145 168 292 10 214 -69 334 -238 361 -73 12 -213 15 -223 4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
19
apps/guide/public/site.webmanifest
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "discord.js guide",
|
||||
"short_name": "discord.js guide",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#1a1b1e",
|
||||
"background_color": "#1a1b1e",
|
||||
"display": "standalone"
|
||||
}
|
||||
3
apps/guide/src/components/DocsLink.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export function DocsLink() {
|
||||
return null;
|
||||
}
|
||||
10
apps/guide/src/components/ExternalLink.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { FiExternalLink } from 'react-icons/fi';
|
||||
|
||||
export function ExternalLink({ href, title }: { href: string; title: string }) {
|
||||
return (
|
||||
<a className="text-blurple inline-flex place-items-center gap-2 text-sm font-semibold" href={href}>
|
||||
<p>{title}</p>
|
||||
<FiExternalLink size={18} />
|
||||
</a>
|
||||
);
|
||||
}
|
||||
70
apps/guide/src/components/Navbar.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { Button } from 'ariakit/button';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { FiCommand } from 'react-icons/fi';
|
||||
import { VscColorMode, VscGithubInverted, VscMenu, VscSearch } from 'react-icons/vsc';
|
||||
import { useMedia } from 'react-use';
|
||||
import { Sidebar } from './Sidebar.jsx';
|
||||
import type { MDXPage } from './SidebarItems.jsx';
|
||||
|
||||
export function Navbar({ pages }: { pages?: MDXPage[] | undefined }) {
|
||||
const matches = useMedia('(min-width: 992px)', false);
|
||||
const [opened, setOpened] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (matches) {
|
||||
setOpened(false);
|
||||
}
|
||||
}, [matches]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<header className="dark:bg-dark-600 dark:border-dark-100 bg-light-600 border-light-800 fixed top-0 left-0 z-20 w-full border-b">
|
||||
<div className="h-18 block px-6">
|
||||
<div className="flex h-full flex-row place-content-between place-items-center">
|
||||
<Button
|
||||
aria-label="Menu"
|
||||
className="focus:ring-width-2 focus:ring-blurple flex h-6 w-6 transform-gpu cursor-pointer select-none appearance-none place-items-center rounded border-0 bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-0 focus:ring active:translate-y-px lg:hidden"
|
||||
onClick={() => setOpened((open) => !open)}
|
||||
>
|
||||
<VscMenu size={24} />
|
||||
</Button>
|
||||
<div className="hidden md:flex md:flex-row">Placeholder</div>
|
||||
<div className="flex flex-row place-items-center gap-4">
|
||||
<Button
|
||||
as="div"
|
||||
className="dark:bg-dark-800 focus:ring-width-2 focus:ring-blurple rounded bg-white px-4 py-2.5 outline-0 focus:ring"
|
||||
// onClick={() => dialog?.toggle()}
|
||||
>
|
||||
<div className="flex flex-row place-items-center gap-4">
|
||||
<VscSearch size={18} />
|
||||
<span className="opacity-65">Search...</span>
|
||||
<div className="opacity-65 flex flex-row place-items-center gap-2">
|
||||
<FiCommand size={18} /> K
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
aria-label="GitHub"
|
||||
as="a"
|
||||
className="focus:ring-width-2 focus:ring-blurple flex h-6 w-6 transform-gpu cursor-pointer select-none appearance-none place-items-center rounded rounded-full border-0 bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-0 focus:ring active:translate-y-px"
|
||||
href="https://github.com/discordjs/discord.js"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<VscGithubInverted size={24} />
|
||||
</Button>
|
||||
<Button
|
||||
aria-label="Toggle theme"
|
||||
className="focus:ring-width-2 focus:ring-blurple flex h-6 w-6 transform-gpu cursor-pointer select-none appearance-none place-items-center rounded-full rounded border-0 bg-transparent p-0 text-sm font-semibold leading-none no-underline outline-0 focus:ring active:translate-y-px"
|
||||
// onClick={() => toggleTheme()}
|
||||
>
|
||||
<VscColorMode size={24} />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<Sidebar opened={opened} pages={pages} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
72
apps/guide/src/components/Outline.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Scrollbars } from 'react-custom-scrollbars-2';
|
||||
import { VscListSelection } from 'react-icons/vsc';
|
||||
import { useLocation } from 'react-use';
|
||||
|
||||
const LINK_HEIGHT = 30;
|
||||
const INDICATOR_SIZE = 10;
|
||||
const INDICATOR_OFFSET = (LINK_HEIGHT - INDICATOR_SIZE) / 2;
|
||||
|
||||
export function Outline({ headings }: { headings: MarkdownHeading[] }) {
|
||||
const state = useLocation();
|
||||
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-0 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="dark:bg-dark-100 bg-light-900 z-30 rounded" />}
|
||||
renderTrackVertical={(props) => (
|
||||
<div {...props} className="absolute top-0.5 right-0.5 bottom-0.5 z-30 w-1.5 rounded" />
|
||||
)}
|
||||
universal
|
||||
>
|
||||
<div className="flex flex-col break-all p-3 pb-8">
|
||||
<div className="mt-4 ml-2 flex flex-row gap-2">
|
||||
<VscListSelection size={25} />
|
||||
<span className="font-semibold">Contents</span>
|
||||
</div>
|
||||
<div className="mt-4 ml-2 flex flex-col gap-2">
|
||||
<div className="relative flex flex-col">
|
||||
<div
|
||||
className="bg-blurple absolute h-[10px] w-[10px] rounded-full border-2 border-black dark:border-white"
|
||||
style={{
|
||||
left: INDICATOR_SIZE / 2 + 0.5,
|
||||
transform: `translateY(${active * LINK_HEIGHT + INDICATOR_OFFSET}px)`,
|
||||
}}
|
||||
/>
|
||||
{headingItems}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Scrollbars>
|
||||
);
|
||||
}
|
||||
13
apps/guide/src/components/PageButton.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export function PageButton({ url, title, direction }: { direction: 'next' | 'prev'; title: string; url: string }) {
|
||||
return (
|
||||
<a
|
||||
className="bg-light-600 hover:bg-light-700 active:bg-light-800 dark:bg-dark-600 dark:hover:bg-dark-500 dark:active:bg-dark-400 focus:ring-width-2 focus:ring-blurple flex transform-gpu cursor-pointer select-none appearance-none flex-row flex-col place-items-center gap-2 rounded py-3 px-4 leading-none no-underline outline-0 focus:ring active:translate-y-px"
|
||||
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>
|
||||
);
|
||||
}
|
||||
3
apps/guide/src/components/ResultingCode.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export function ResultingCode() {
|
||||
return null;
|
||||
}
|
||||
24
apps/guide/src/components/Sidebar.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Scrollbars } from 'react-custom-scrollbars-2';
|
||||
import type { MDXPage } from './SidebarItems.jsx';
|
||||
|
||||
export function Sidebar({ pages, opened }: { opened: boolean; pages?: MDXPage[] | undefined }) {
|
||||
return (
|
||||
<nav
|
||||
className={`h-[calc(100vh - 73px)] dark:bg-dark-600 dark:border-dark-100 border-light-800 fixed top-[73px] left-0 bottom-0 z-20 w-full border-r bg-white ${
|
||||
opened ? 'block' : 'hidden'
|
||||
} lg:w-76 lg:max-w-76 lg:block`}
|
||||
>
|
||||
<Scrollbars
|
||||
autoHide
|
||||
hideTracksWhenNotNeeded
|
||||
renderThumbVertical={(props) => <div {...props} className="dark:bg-dark-100 bg-light-900 z-30 rounded" />}
|
||||
renderTrackVertical={(props) => (
|
||||
<div {...props} className="absolute top-0.5 right-0.5 bottom-0.5 z-30 w-1.5 rounded" />
|
||||
)}
|
||||
universal
|
||||
>
|
||||
{pages ?? null}
|
||||
</Scrollbars>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
51
apps/guide/src/components/SidebarItems.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Section } from '@discordjs/ui';
|
||||
import type { MDXInstance } from 'astro';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useLocation } from 'react-use';
|
||||
|
||||
export type MDXPage = MDXInstance<{ category: string; title: string }>;
|
||||
|
||||
export function SidebarItems({ pages }: { pages: MDXPage[] }) {
|
||||
const state = useLocation();
|
||||
const [active, setActive] = useState<string | undefined>('');
|
||||
|
||||
const categories = useMemo(
|
||||
() =>
|
||||
pages.reduce<Record<string, MDXPage[]>>((acc, page) => {
|
||||
if (acc[page.frontmatter.category]) {
|
||||
acc[page.frontmatter.category]?.push(page);
|
||||
} else {
|
||||
acc[page.frontmatter.category] = [page];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {}),
|
||||
[pages],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setActive(state.pathname);
|
||||
}, [state]);
|
||||
|
||||
return Object.keys(categories).map((category, idx) => (
|
||||
<Section key={idx} title={category}>
|
||||
{categories[category]?.map((member, index) => (
|
||||
<a
|
||||
className={`dark:border-dark-100 border-light-800 focus:ring-width-2 focus:ring-blurple ml-5 flex flex-col border-l p-[5px] pl-6 outline-0 focus:rounded focus:border-0 focus:ring ${
|
||||
(member.url || '/') === active
|
||||
? 'bg-blurple text-white'
|
||||
: 'dark:hover:bg-dark-200 dark:active:bg-dark-100 hover:bg-light-700 active:bg-light-800'
|
||||
}`}
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
||||
href={member.url || '/'}
|
||||
key={index}
|
||||
title={member.frontmatter.title}
|
||||
>
|
||||
<div className="flex flex-row place-items-center gap-2 lg:text-sm">
|
||||
<span className="truncate">{member.frontmatter.title}</span>
|
||||
</div>
|
||||
</a>
|
||||
)) ?? null}
|
||||
</Section>
|
||||
));
|
||||
}
|
||||
180
apps/guide/src/components/SidebarLayout.astro
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
import { Separator } from 'ariakit/separator';
|
||||
import type { MarkdownLayoutProps } from 'astro';
|
||||
import { ExternalLink } from './ExternalLink.jsx';
|
||||
import { Navbar } from './Navbar.jsx';
|
||||
import { Outline } from './Outline.jsx';
|
||||
import { PageButton } from './PageButton.jsx';
|
||||
import { SidebarItems } from './SidebarItems.jsx';
|
||||
import { generateGithubURL } from '~/util/url.js';
|
||||
|
||||
const pages = await Astro.glob<{ category: string; title: string }>('../pages/**/*.mdx');
|
||||
|
||||
type Props = MarkdownLayoutProps<{}>;
|
||||
const { headings, url, frontmatter } = Astro.props;
|
||||
|
||||
const groupedPages = pages.reduce<Record<string, typeof pages>>((acc, page) => {
|
||||
const { category } = page.frontmatter;
|
||||
acc[category] ??= [];
|
||||
|
||||
acc[category]?.push(page);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// @ts-expect-error props is not typed
|
||||
const category = frontmatter.category as string;
|
||||
|
||||
const curCategoryPages = groupedPages[category];
|
||||
const curCategoryIndex = curCategoryPages!.findIndex((page) => page.url === url);
|
||||
|
||||
const pagePrev = curCategoryPages![curCategoryIndex - 1];
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||
const pageNext = curCategoryPages![curCategoryIndex + 1];
|
||||
---
|
||||
|
||||
<script>
|
||||
window.addEventListener('load', () => {
|
||||
const headings = document.querySelectorAll(
|
||||
'div.level-h1 > h1, div.level-h2 > h2, div.level-h3 > h3, div.level-h4 > h4',
|
||||
);
|
||||
|
||||
const headingsObserver = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const location = window.location.toString().split('#')[0];
|
||||
history.replaceState(null, '', location + '#' + entry.target.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
{
|
||||
root: null,
|
||||
rootMargin: '-100px 0% -66%',
|
||||
threshold: 1.0,
|
||||
},
|
||||
);
|
||||
|
||||
headings.forEach((heading) => headingsObserver.observe(heading));
|
||||
});
|
||||
</script>
|
||||
|
||||
<Navbar client:load>
|
||||
<div class="flex flex-col gap-3 p-3 pb-32 lg:pb-12" slot="pages">
|
||||
<SidebarItems client:load pages={pages} />
|
||||
</div>
|
||||
</Navbar>
|
||||
<main class="pt-18 lg:pl-76 xl:pr-64">
|
||||
<article class="dark:bg-dark-600 bg-light-600">
|
||||
<div class="dark:bg-dark-800 relative z-10 min-h-[calc(100vh_-_70px)] bg-white p-6 pb-20 shadow">
|
||||
<div class="prose max-w-full">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="h-[calc(100vh - 72px)] dark:bg-dark-600 dark:border-dark-100 border-light-800 fixed top-[72px] right-0 bottom-0 z-20 hidden w-64 border-l bg-white pr-2 xl:block"
|
||||
>
|
||||
<Outline client:load headings={headings} />
|
||||
</div>
|
||||
<Separator className="my-5 border-light-800 dark:border-dark-100" />
|
||||
<div class="flex flex-col space-y-5">
|
||||
<div class="flex place-content-end">
|
||||
<ExternalLink client:load href={generateGithubURL(url!)} title="Edit this page on github" />
|
||||
</div>
|
||||
<div class="flex w-full">
|
||||
{
|
||||
pagePrev && (
|
||||
<PageButton
|
||||
direction="prev"
|
||||
title={pagePrev.frontmatter.title}
|
||||
url={pagePrev.url === '' ? '/' : pagePrev.url!}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div class="ml-auto self-end justify-self-end">
|
||||
{
|
||||
pageNext && (
|
||||
<PageButton
|
||||
direction="next"
|
||||
title={pageNext.frontmatter.title}
|
||||
url={pageNext.url === '' ? '/' : pageNext.url!}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="h-76 md:h-52"></div>
|
||||
<footer
|
||||
class="dark:bg-dark-600 h-76 lg:pl-84 bg-light-600 xl:pr-76 fixed bottom-0 left-0 right-0 md:h-52 md:pl-4 md:pr-16"
|
||||
>
|
||||
<div class="mx-auto flex max-w-6xl flex-col place-items-center gap-12 pt-12 lg:place-content-center">
|
||||
<div class="flex w-full flex-col place-content-between place-items-center gap-12 md:flex-row md:gap-0">
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://vercel.com/?utm_source=discordjs&utm_campaign=oss"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
title="Vercel"
|
||||
>
|
||||
<img alt="Vercel" src="/powered-by-vercel.svg" />
|
||||
</a>
|
||||
<div class="flex flex-row gap-6 md:gap-12">
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-lg font-semibold">Community</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://discord.gg/djs"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://github.com/discordjs/discord.js/discussions"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
GitHub discussions
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="text-lg font-semibold">Project</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://github.com/discordjs/discord.js"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
discord.js
|
||||
</a>
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://discordjs.guide"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
discord.js guide
|
||||
</a>
|
||||
<a
|
||||
class="focus:ring-width-2 focus:ring-blurple rounded outline-0 focus:ring"
|
||||
href="https://discord-api-types.dev"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
discord-api-types
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
<div>Test</div>
|
||||
</main>
|
||||
63
apps/guide/src/layouts/SidebarLayout.astro
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
import '../styles/main.css';
|
||||
import '@code-hike/mdx/styles.css';
|
||||
import '../styles/ch.css';
|
||||
import type { MarkdownLayoutProps } from 'astro';
|
||||
import SidebarLayout from '../components/SidebarLayout.astro';
|
||||
import { DESCRIPTION } from '../util/constants.js';
|
||||
|
||||
type Props = MarkdownLayoutProps<{}>;
|
||||
const props = Astro.props;
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link href="/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180" />
|
||||
<link href="/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png" />
|
||||
<link href="/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png" />
|
||||
<link href="/site.webmanifest" rel="manifest" />
|
||||
<link color="#090a16" href="/safari-pinned-tab.svg" rel="mask-icon" />
|
||||
<meta content="light dark" name="color-scheme" />
|
||||
<meta content="discord.js" name="apple-mobile-web-app-title" />
|
||||
<meta content="discord.js" name="application-name" />
|
||||
<meta content="#090a16" name="msapplication-TileColor" />
|
||||
<meta content={DESCRIPTION} name="description" />
|
||||
<meta content="discord.js" property="og:site_name" />
|
||||
<meta content="website" property="og:type" />
|
||||
<meta content="discord.js guide" property="og:title" />
|
||||
<meta content={DESCRIPTION} name="og:description" />
|
||||
<meta content="https://discordjs.dev/open-graph.png" property="og:image" />
|
||||
<meta content="summary_large_image" name="twitter:card" />
|
||||
<meta content="@iCrawlToGo" name="twitter:creator" />
|
||||
|
||||
<title>discord.js</title>
|
||||
<meta content="minimum-scale=1, initial-scale=1, width=device-width" name="viewport" />
|
||||
<meta content="#5865f2" name="theme-color" />
|
||||
</head>
|
||||
<body class="dark:bg-dark-800 bg-white">
|
||||
<script is:inline>
|
||||
function setTheme(prefersDarkMode, persistedColorPreference) {
|
||||
if (persistedColorPreference === 'dark' || (prefersDarkMode && persistedColorPreference !== 'light')) {
|
||||
document.documentElement.classList.toggle('dark', true);
|
||||
} else {
|
||||
document.documentElement.classList.toggle('dark', false);
|
||||
}
|
||||
}
|
||||
|
||||
(() => {
|
||||
const prefersDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const persistedColorPreference = localStorage.getItem('theme') || 'auto';
|
||||
setTheme(prefersDarkMode, persistedColorPreference);
|
||||
|
||||
const listener =
|
||||
window.matchMedia &&
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', (ev) => setTheme(ev.matches, persistedColorPreference));
|
||||
})();
|
||||
</script>
|
||||
<SidebarLayout {...props}>
|
||||
<slot />
|
||||
</SidebarLayout>
|
||||
</body>
|
||||
</html>
|
||||
253
apps/guide/src/pages/additional-info/async-await.mdx
Normal file
@@ -0,0 +1,253 @@
|
||||
---
|
||||
layout: '../../layouts/SidebarLayout.astro'
|
||||
title: Understanding async/await
|
||||
category: Additional info
|
||||
---
|
||||
|
||||
import { CH } from '@code-hike/mdx/components';
|
||||
import { Alert } from '@discordjs/ui';
|
||||
|
||||
# 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 client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```js
|
||||
async function declaredAsAsync() {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
or
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js
|
||||
const declaredAsAsync = async () => {
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
You can use that as well if you use the arrow function as an event listener.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```js
|
||||
const { Client, GatewayIntentBits } = require('discord.js');
|
||||
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||
|
||||
client.once('ready', () => {
|
||||
console.log('I am ready!');
|
||||
});
|
||||
|
||||
client.on('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 client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```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/en-US/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 client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```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.
|
||||
127
apps/guide/src/pages/additional-info/collections.mdx
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: '../../layouts/SidebarLayout.astro'
|
||||
title: Collections
|
||||
category: Additional info
|
||||
---
|
||||
|
||||
import { CH } from '@code-hike/mdx/components';
|
||||
import { Alert } from '@discordjs/ui';
|
||||
|
||||
# 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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) before continuing. You
|
||||
should be familiar with _`Array`_
|
||||
[methods](https://developer.mozilla.org/en-US/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 client:load>
|
||||
|
||||
```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/en-US/docs/Web/JavaScript/Reference/Iteration_protocols), and can be converted to an _`Array`_ through either _`Array.from()`_ or spread syntax (_`...collection`_).
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```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 client:load>
|
||||
|
||||
```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`\_s, but done at the same time:
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```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>
|
||||
250
apps/guide/src/pages/creating-your-bot/creating-commands.mdx
Normal file
@@ -0,0 +1,250 @@
|
||||
---
|
||||
layout: '../../layouts/SidebarLayout.astro'
|
||||
title: Creating commands
|
||||
category: Creating your bot
|
||||
---
|
||||
|
||||
import { CH } from '@code-hike/mdx/components';
|
||||
import { Alert, DiscordMessages, DiscordMessage } from '@discordjs/ui';
|
||||
import { DocsLink } from '../../components/DocsLink.jsx';
|
||||
import { ResultingCode } from '../../components/ResultingCode.jsx';
|
||||
|
||||
# Creating commands
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
This page is a follow-up and bases its code on [the previous page](/creating-your-bot/).
|
||||
</Alert>
|
||||
|
||||
<DiscordMessages rounded>
|
||||
<DiscordMessage
|
||||
interaction={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
command: 'ping',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
Pong!
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
Discord allows developers to register [slash commands](https://discord.com/developers/docs/interactions/application-commands), which provide users a first-class way of interacting directly with your application. Before being able to reply to a command, you must first register it.
|
||||
|
||||
## Registering commands
|
||||
|
||||
This section will cover only the bare minimum to get you started, but you can refer to our [in-depth page on registering slash commands](/interactions/slash-commands.md#registering-slash-commands) for further details. It covers guild commands, global commands, options, option types, and choices.
|
||||
|
||||
### Command deployment script
|
||||
|
||||
Create a _`deploy-commands.js`_ file in your project directory. This file will be used to register and update the slash commands for your bot application.
|
||||
|
||||
Since commands only need to be registered once, and updated when the definition (description, options etc) is changed, it's not necessary to connect a whole client to the gateway or do this on every _`ready`_ event. As such, a standalone script using the lighter REST manager is preferred.
|
||||
|
||||
Below is a deployment script you can use. Focus on these variables:
|
||||
|
||||
- _`clientId`_: Your application's client id
|
||||
- _`guildId`_: Your development server's id
|
||||
- _`commands`_: An array of commands to register. The [slash command builder](/popular-topics/builders.md#slash-command-builders) from _`discord.js`_ is used to build the data for your commands
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
In order to get your application's client id, go to [Discord Developer
|
||||
Portal](https://discord.com/developers/applications) and choose your application. Find the id under "Application ID"
|
||||
in General Information subpage. To get guild id, open Discord and go to your settings. On the "Advanced" page, turn on
|
||||
"Developer Mode". This will enable a "Copy ID" button in the context menu when you right-click on a server icon, a
|
||||
user's profile, etc.
|
||||
</Alert>
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js deploy-commands.js mark=4,6:10
|
||||
const { REST, SlashCommandBuilder, Routes } = require('discord.js');
|
||||
const { clientId, guildId, token } = require('./config.json');
|
||||
|
||||
const commands = [
|
||||
new SlashCommandBuilder().setName('ping').setDescription('Replies with pong!'),
|
||||
new SlashCommandBuilder().setName('server').setDescription('Replies with server info!'),
|
||||
new SlashCommandBuilder().setName('user').setDescription('Replies with user info!'),
|
||||
].map((command) => command.toJSON());
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(token);
|
||||
|
||||
rest
|
||||
.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands })
|
||||
.then((data) => console.log(`Successfully registered ${data.length} application commands.`))
|
||||
.catch(console.error);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```json config.json mark=2:3
|
||||
{
|
||||
"clientId": "123456789012345678",
|
||||
"guildId": "876543210987654321",
|
||||
"token": "your-token-goes-here"
|
||||
}
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
Once you fill in these values, run _`node deploy-commands.js`_ in your project directory to register your commands to a single guild. It's also possible to [register commands globally](/interactions/slash-commands.md#global-commands).
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
You only need to run `node deploy-commands.js` once. You should only run it again if you add or edit existing
|
||||
commands.
|
||||
</Alert>
|
||||
|
||||
## Replying to commands
|
||||
|
||||
Once you've registered your commands, you can listen for interactions via <DocsLink path="class/Client?scrollTo=e-interactionCreate" /> in your _`index.js`_ file.
|
||||
|
||||
You should first check if an interaction is a chat input command via <DocsLink path="class/Interaction?scrollTo=isChatInputCommand" type="method">_`.isChatInputCommand()`_</DocsLink>, and then check the <DocsLink path="class/CommandInteraction?scrollTo=commandName">_`.commandName`_</DocsLink> property to know which command it is. You can respond to interactions with <DocsLink path="class/CommandInteraction?scrollTo=reply">_`.reply()`_</DocsLink>.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js mark=5:16
|
||||
client.once('ready', () => {
|
||||
console.log('Ready!');
|
||||
});
|
||||
|
||||
client.on('interactionCreate', async (interaction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
const { commandName } = interaction;
|
||||
if (commandName === 'ping') {
|
||||
await interaction.reply('Pong!');
|
||||
} else if (commandName === 'server') {
|
||||
await interaction.reply('Server info.');
|
||||
} else if (commandName === 'user') {
|
||||
await interaction.reply('User info.');
|
||||
}
|
||||
});
|
||||
client.login(token);
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
### Server info command
|
||||
|
||||
Note that servers are referred to as "guilds" in the Discord API and discord.js library. _`interaction.guild`_ refers to the guild the interaction was sent in (a <DocsLink path="class/Guild" /> instance), which exposes properties such as _`.name`_ or _`.memberCount`_.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js focus=7
|
||||
client.on('interactionCreate', async (interaction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
const { commandName } = interaction;
|
||||
if (commandName === 'ping') {
|
||||
await interaction.reply('Pong!');
|
||||
} else if (commandName === 'server') {
|
||||
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
|
||||
} else if (commandName === 'user') {
|
||||
await interaction.reply('User info.');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
<DiscordMessages rounded>
|
||||
<DiscordMessage
|
||||
interaction={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
command: 'server',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
<p>Server name: discord.js Guide</p>
|
||||
<p>Total members: 2</p>
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
You could also display the date the server was created, or the server's verification level. You would do those in the same manner – use _`interaction.guild.createdAt`_ or _`interaction.guild.verificationLevel`_, respectively.
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
Refer to the <DocsLink path="class/Guild" /> documentation for a list of all the available properties and methods!
|
||||
</Alert>
|
||||
|
||||
### User info command
|
||||
|
||||
A "user" refers to a Discord user. _`interaction.user`_ refers to the user the interaction was sent by (a <DocsLink path="class/User" /> instance), which exposes properties such as _`.tag`_ or _`.id`_.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js focus=9
|
||||
client.on('interactionCreate', async (interaction) => {
|
||||
if (!interaction.isChatInputCommand()) return;
|
||||
const { commandName } = interaction;
|
||||
if (commandName === 'ping') {
|
||||
await interaction.reply('Pong!');
|
||||
} else if (commandName === 'server') {
|
||||
await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
|
||||
} else if (commandName === 'user') {
|
||||
await interaction.reply(`Your tag: ${interaction.user.tag}\nYour id: ${interaction.user.id}`);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
<DiscordMessages rounded>
|
||||
<DiscordMessage
|
||||
interaction={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
command: 'user',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
<p>Your tag: User#0001</p>
|
||||
<p>Your id: 123456789012345678</p>
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
Refer to the <DocsLink path="class/User" /> documentation for a list of all the available properties and methods!
|
||||
</Alert>
|
||||
|
||||
And there you have it!
|
||||
|
||||
## The problem with if/else if
|
||||
|
||||
If you don't plan on making more than a couple commands, then using an _`if`_/_`else if`_ chain is fine; however, this isn't always the case. Using a giant _`if`_/_`else if`_ chain will only hinder your development process in the long run.
|
||||
|
||||
Here's a small list of reasons why you shouldn't do so:
|
||||
|
||||
- Takes longer to find a piece of code you want;
|
||||
- Easier to fall victim to [spaghetti code](https://en.wikipedia.org/wiki/Spaghetti_code);
|
||||
- Difficult to maintain as it grows;
|
||||
- Difficult to debug;
|
||||
- Difficult to organize;
|
||||
- General bad practice.
|
||||
|
||||
Next, we'll be diving into something called a "command handler" – code that makes handling commands easier and much more efficient. This allows you to move your commands into individual files.
|
||||
|
||||
## Resulting code
|
||||
|
||||
<ResultingCode />
|
||||
194
apps/guide/src/pages/creating-your-bot/index.mdx
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
layout: '../../layouts/SidebarLayout.astro'
|
||||
title: Initial files
|
||||
category: Creating your bot
|
||||
---
|
||||
|
||||
import { CH } from '@code-hike/mdx/components';
|
||||
import { Alert, Section } from '@discordjs/ui';
|
||||
import { DocsLink } from '../../components/DocsLink.jsx';
|
||||
import { ResultingCode } from '../../components/ResultingCode.jsx';
|
||||
|
||||
# Initial files
|
||||
|
||||
Once you [add your bot to a server](/preparations/adding-your-bot-to-servers.md), the next step is to start coding and get it online! Let's start by creating a config file for your client token and a main file for your bot application.
|
||||
|
||||
## Creating configuration files
|
||||
|
||||
As explained in the ["What is a token, anyway?"](/preparations/setting-up-a-bot-application.md#what-is-a-token-anyway) section, your token is essentially your bot's password, and you should protect it as best as possible. This can be done through a _`config.json`_ file or by using environment variables.
|
||||
|
||||
Open your application in the [Discord Developer Portal](https://discord.com/developers/applications) and go to the "Bot" page to copy your token.
|
||||
|
||||
### Using config.json
|
||||
|
||||
Storing data in a _`config.json`_ file is a common way of keeping your sensitive values safe. Create a _`config.json`_ file in your project directory and paste in your token. You can access your token inside other files by using _`require()`_.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```json config.json
|
||||
{
|
||||
"token": "your-token-goes-here"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```js Usage
|
||||
const { token } = require('./config.json');
|
||||
|
||||
console.log(token);
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
<Alert title="Caution" type="danger">
|
||||
If you're using Git, you should not commit this file and should [ignore it via
|
||||
_`.gitignore`_](/creating-your-bot/#git-and-gitignore).
|
||||
</Alert>
|
||||
|
||||
### Using environment variables
|
||||
|
||||
Environment variables are special values for your environment (e.g., terminal session, Docker container, or environment variable file). You can pass these values into your code's scope so that you can use them.
|
||||
|
||||
One way to pass in environment variables is via the command line interface. When starting your app, instead of _`node index.js`_, use _`TOKEN=your-token-goes-here node index.js`_. You can repeat this pattern to expose other values as well.
|
||||
|
||||
You can access the set values in your code via the _`process.env`_ global variable, accessible in any file. Note that values passed this way will always be strings and that you might need to parse them to a number, if using them to do calculations.
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```shellscript Command line
|
||||
A=123 B=456 DISCORD_TOKEN=your-token-goes-here node index.js
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```js Usage
|
||||
console.log(process.env.A);
|
||||
console.log(process.env.B);
|
||||
console.log(process.env.DISCORD_TOKEN);
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
#### Using dotenv
|
||||
|
||||
Another common approach is storing these values in a _`.env`_ file. This spares you from always copying your token into the command line. Each line in a _`.env`_ file should hold a _`KEY=value`_ pair.
|
||||
|
||||
You can use the [_`dotenv`_ package](https://www.npmjs.com/package/dotenv) for this. Once installed, require and use the package to load your _`.env`_ file and attach the variables to _`process.env`_:
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```shellscript npm
|
||||
npm install dotenv
|
||||
```
|
||||
|
||||
```shellscript yarn
|
||||
yarn add dotenv
|
||||
```
|
||||
|
||||
```shellscript pnpm
|
||||
pnpm add dotenv
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```text .env
|
||||
A=123
|
||||
B=456
|
||||
DISCORD_TOKEN=your-token-goes-here
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
```js Usage
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
dotenv.config();
|
||||
|
||||
console.log(process.env.A);
|
||||
console.log(process.env.B);
|
||||
console.log(process.env.DISCORD_TOKEN);
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
<Alert title="Caution" type="danger">
|
||||
If you're using Git, you should not commit this file and should [ignore it via
|
||||
_`.gitignore`_](/creating-your-bot/#git-and-gitignore).
|
||||
</Alert>
|
||||
|
||||
<Section client:load title="Online editors (Glitch, Heroku, Replit, etc.)" defaultClosed padded background gutter>
|
||||
While we generally do not recommend using online editors as hosting solutions, but rather invest in a proper virtual private server, these services do offer ways to keep your credentials safe as well! Please see the respective service's documentation and help articles for more information on how to keep sensitive values safe:
|
||||
|
||||
- Glitch: [Storing secrets in .env](https://glitch.happyfox.com/kb/article/18)
|
||||
- Heroku: [Configuration variables](https://devcenter.heroku.com/articles/config-vars)
|
||||
- Replit: [Secrets and environment variables](https://docs.replit.com/repls/secrets-environment-variables)
|
||||
|
||||
</Section>
|
||||
|
||||
### Git and .gitignore
|
||||
|
||||
Git is a fantastic tool to keep track of your code changes and allows you to upload progress to services like [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), or [Bitbucket](https://bitbucket.org/product). While this is super useful to share code with other developers, it also bears the risk of uploading your configuration files with sensitive values!
|
||||
|
||||
You can specify files that Git should ignore in its versioning systems with a _`.gitignore`_ file. Create a _`.gitignore`_ file in your project directory and add the names of the files and folders you want to ignore:
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```
|
||||
node_modules
|
||||
.env
|
||||
config.json
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
Aside from keeping credentials safe, _`node_modules`_ should be included here. Since this directory can be restored
|
||||
based on the entries in your _`package.json`_ and _`package-lock.json`_ files by running _`npm install`_, it does not
|
||||
need to be included in Git. You can specify quite intricate patterns in _`.gitignore`_ files, check out the [Git
|
||||
documentation on _`.gitignore`_](https://git-scm.com/docs/gitignore) for more information!
|
||||
</Alert>
|
||||
|
||||
## Creating the main file
|
||||
|
||||
Open your code editor and create a new file. We suggest that you save the file as _`index.js`_, but you may name it whatever you wish.
|
||||
|
||||
Here's the base code to get you started:
|
||||
|
||||
<CH.Code client:load>
|
||||
|
||||
```js
|
||||
// Require the necessary discord.js classes
|
||||
const { Client, GatewayIntentBits } = require('discord.js');
|
||||
const { token } = require('./config.json');
|
||||
|
||||
// Create a new client instance
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
|
||||
|
||||
// When the client is ready, run this code (only once)
|
||||
client.once('ready', () => {
|
||||
console.log('Ready!');
|
||||
});
|
||||
|
||||
// Login to Discord with your client's token
|
||||
client.login(token);
|
||||
```
|
||||
|
||||
</CH.Code>
|
||||
|
||||
This is how you create a client instance for your Discord bot and login to Discord. The _`GatewayIntentBits.Guilds`_ intents option is necessary for your client to work properly, as it ensures that the caches for guilds, channels and roles are populated and available for internal use.
|
||||
|
||||
Intents also define which events Discord should send to your bot, and you may wish to enable more than just the minimum. You can read more about the other intents on the [Intents topic](/popular-topics/intents).
|
||||
|
||||
Open your terminal and run _`node index.js`_ to start the process. If you see "Ready!" after a few seconds, you're good to go!
|
||||
|
||||
<Alert title="Tip" type="success">
|
||||
You can open your _`package.json`_ file and edit the _`"main": "index.js"`_ field to point to your main file. You can
|
||||
then run _`node .`_ in your terminal to start the process! After closing the process with _`Ctrl + C`_, you can press
|
||||
the up arrow on your keyboard to bring up the latest commands you've run. Pressing up and then enter after closing the
|
||||
process is a quick way to start it up again.
|
||||
</Alert>
|
||||
|
||||
## Resulting code
|
||||
|
||||
<ResultingCode path="creating-your-bot/initial-files" />
|
||||
36
apps/guide/src/pages/index.mdx
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
layout: '../layouts/SidebarLayout.astro'
|
||||
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](/preparations/) from scratch;
|
||||
- How to properly [create](/creating-your-bot/), [organize](/creating-your-bot/command-handling.md), and expand on your commands;
|
||||
- In-depth explanations and examples regarding popular topics (e.g. [reactions](/popular-topics/reactions.md), [embeds](/popular-topics/embeds.md), [canvas](/popular-topics/canvas.md));
|
||||
- Working with databases (e.g. [sequelize](/sequelize/) and [keyv](/keyv/));
|
||||
- Getting started with [sharding](/sharding/);
|
||||
- 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, then.
|
||||
|
||||
## 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://www.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/en-US/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!
|
||||
20
apps/guide/src/pages/requesting-more-content.mdx
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
layout: '../layouts/SidebarLayout.astro'
|
||||
title: Requesting more content
|
||||
category: Home
|
||||
---
|
||||
|
||||
import { Alert } from '@discordjs/ui';
|
||||
|
||||
# Requesting more content
|
||||
|
||||
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](/popular-topics/faq.html) page", or as elaborate as "add a page regarding [sharding](/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 repo's issue tracker](https://github.com/discordjs/guide/issues) and [create a new issue](https://github.com/discordjs/guide/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="success">
|
||||
Remember that you can always [fork the repo](https://github.com/discordjs/guide) and [make a pull
|
||||
request](https://github.com/discordjs/guide/pulls) if you want to add anything to the guide yourself!
|
||||
</Alert>
|
||||
102
apps/guide/src/pages/test.mdx
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Test
|
||||
category: Test
|
||||
---
|
||||
|
||||
import { DiscordMessages, DiscordMessage, DiscordMessageEmbed } from '@discordjs/ui';
|
||||
|
||||
<DiscordMessages>
|
||||
<DiscordMessage
|
||||
reply={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
content: 'Test',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
1234
|
||||
</DiscordMessage>
|
||||
<DiscordMessage
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
followUp
|
||||
time="21:02"
|
||||
>
|
||||
1234
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
<DiscordMessages>
|
||||
<DiscordMessage
|
||||
reply={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
content: 'Test',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
1234
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
<DiscordMessages>
|
||||
<DiscordMessage
|
||||
reply={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
content: 'Test',
|
||||
}}
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
<>
|
||||
<DiscordMessageEmbed
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
}}
|
||||
/>
|
||||
<DiscordMessageEmbed title={{ title: 'Title' }} />
|
||||
<DiscordMessageEmbed footer={{ content: 'Footer' }} />
|
||||
<DiscordMessageEmbed
|
||||
author={{
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
}}
|
||||
title={{ title: 'Title' }}
|
||||
footer={{ content: 'Footer' }}
|
||||
>
|
||||
Test
|
||||
</DiscordMessageEmbed>
|
||||
</>
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
75
apps/guide/src/pages/whats-new.mdx
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
layout: '../layouts/SidebarLayout.astro'
|
||||
title: What's new
|
||||
category: Home
|
||||
---
|
||||
|
||||
import { CH } from '@code-hike/mdx/components';
|
||||
import { DiscordMessages, DiscordMessage } from '@discordjs/ui';
|
||||
|
||||
# What's new
|
||||
|
||||
<DiscordMessages rounded>
|
||||
<DiscordMessage
|
||||
interaction={{
|
||||
author: {
|
||||
avatar:
|
||||
'https://cdn.discordapp.com/guilds/222078108977594368/users/81440962496172032/avatars/c059c5d04d717ea05790f7a6447e4843.webp?size=160',
|
||||
username: 'Crawl',
|
||||
},
|
||||
command: 'upgrade',
|
||||
}}
|
||||
author={{
|
||||
avatar: 'https://cdn.discordapp.com/avatars/474807795183648809/7f239a0776ff928b2182906a2b3743c9.webp?size=160',
|
||||
bot: true,
|
||||
username: 'Guide Bot',
|
||||
time: 'Today at 21:00',
|
||||
}}
|
||||
>
|
||||
discord.js v14 has released and the guide has been updated!
|
||||
<br />
|
||||
This includes additions and changes made in Discord, such as slash commands and message components.
|
||||
</DiscordMessage>
|
||||
</DiscordMessages>
|
||||
|
||||
## Site
|
||||
|
||||
- Upgraded to [VuePress v2](https://v2.vuepress.vuejs.org/)
|
||||
- New theme made to match the [discord.js documentation site](https://discord.js.org/)
|
||||
- Discord message components upgraded to [@discord-message-components/vue](https://github.com/Danktuary/discord-message-components/blob/main/packages/vue/README.md)
|
||||
- Many fixes in code blocks, grammar, consistency, etc.
|
||||
|
||||
## Pages
|
||||
|
||||
All content has been updated to use discord.js v14 syntax. The v13 version of the guide can be found at [https://v13.discordjs.guide/](https://v13.discordjs.guide/).
|
||||
|
||||
### New
|
||||
|
||||
- [Updating from v13 to v14](/additional-info/changes-in-v14.md): A list of the changes from discord.js v13 to v14
|
||||
- [Slash commands](/interactions/slash-commands.md): Registering, replying to slash commands and permissions
|
||||
- [Buttons](/interactions/buttons.md): Building, sending, and receiving buttons
|
||||
- [Select menus](/interactions/select-menus.md): Building, sending, and receiving select menus
|
||||
- [Threads](/popular-topics/threads.md): Creating and managing threads
|
||||
- [Builders](/popular-topics/builders.md): A collection of builders to use with your bot
|
||||
|
||||
### Updated
|
||||
|
||||
- Commando: Replaced with [Sapphire](https://sapphirejs.dev/docs/Guide/getting-started/getting-started-with-sapphire)
|
||||
- [Voice](/voice/): Rewritten to use the [_`@discordjs/voice`_](https://github.com/discordjs/discord.js/tree/main/packages/voice) package
|
||||
- [Command handling](/creating-your-bot/command-handling.md/): Updated to use slash commands
|
||||
- Obsolete sections removed
|
||||
- _`client.on('message')`_ snippets updated to _`client.on('interactionCreate')`_
|
||||
- [Message content will become a new privileged intent on August 31, 2022](https://support-dev.discord.com/hc/en-us/articles/4404772028055)
|
||||
|
||||
<DiscordMessages rounded>
|
||||
<DiscordMessage
|
||||
author={{
|
||||
avatar: 'https://cdn.discordapp.com/avatars/474807795183648809/7f239a0776ff928b2182906a2b3743c9.webp?size=160',
|
||||
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>
|
||||
3
apps/guide/src/styles/ch.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.ch-frame-buttons {
|
||||
display: none;
|
||||
}
|
||||
16
apps/guide/src/styles/main.css
Normal file
@@ -0,0 +1,16 @@
|
||||
@import url('https://rsms.me/inter/inter.css');
|
||||
|
||||
:root {
|
||||
font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
|
||||
}
|
||||
|
||||
@supports (font-variation-settings: normal) {
|
||||
:root {
|
||||
font-family: 'Inter var', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
|
||||
'Noto Color Emoji';
|
||||
}
|
||||
}
|
||||
3
apps/guide/src/util/constants.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export const DESCRIPTION = 'Imagine a guide... that explores the many possibilities for your discord.js bot.';
|
||||
|
||||
export const GITHUB_BASE_PAGES_PATH = 'https://github.com/discordjs/discord.js/tree/main/apps/guide/src/pages';
|
||||
5
apps/guide/src/util/url.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { GITHUB_BASE_PAGES_PATH } from './constants.js';
|
||||
|
||||
export function generateGithubURL(pageURL: string) {
|
||||
return `${GITHUB_BASE_PAGES_PATH}${pageURL}.mdx`;
|
||||
}
|
||||
22
apps/guide/tsconfig.eslint.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
"**/*.js",
|
||||
"**/*.cjs",
|
||||
"**/*.mjs",
|
||||
"**/*.jsx",
|
||||
"**/*.astro",
|
||||
"**/*.test.ts",
|
||||
"**/*.test.js",
|
||||
"**/*.test.mjs",
|
||||
"**/*.spec.ts",
|
||||
"**/*.spec.js",
|
||||
"**/*.spec.mjs"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
19
apps/guide/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"baseUrl": ".",
|
||||
"noEmit": true,
|
||||
"allowJs": false,
|
||||
"incremental": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["@astrojs/image/client"],
|
||||
"paths": {
|
||||
"~/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "types.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
1
apps/guide/types.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module '*.css';
|
||||
3
apps/guide/vercel.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"cleanUrls": true
|
||||
}
|
||||
1
apps/website/.env.development
Normal file
@@ -0,0 +1 @@
|
||||
NEXT_PUBLIC_LOCAL_DEV=true
|
||||
12
apps/website/.eslintrc.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json", "neon/react", "neon/next", "neon/edge", "neon/prettier"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"react/react-in-jsx-scope": 0,
|
||||
"react/jsx-filename-extension": [1, { "extensions": [".tsx"] }]
|
||||
}
|
||||
}
|
||||
30
apps/website/.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# Packages
|
||||
node_modules/
|
||||
|
||||
# Log files
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Env
|
||||
.env
|
||||
|
||||
# Dist
|
||||
dist/
|
||||
typings/
|
||||
.cache/
|
||||
build/
|
||||
src/styles/unocss.css
|
||||
.next/
|
||||
|
||||
# Miscellaneous
|
||||
.tmp/
|
||||
coverage/
|
||||
.vercel
|
||||
public/searchIndex
|
||||
.vscode
|
||||
1
apps/website/.lintstagedrc.cjs
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('../../.lintstagedrc.json');
|
||||
16
apps/website/.prettierignore
Normal file
@@ -0,0 +1,16 @@
|
||||
# Autogenerated
|
||||
CHANGELOG.md
|
||||
.turbo
|
||||
dist/
|
||||
docs/**/*
|
||||
!docs/index.yml
|
||||
!docs/README.md
|
||||
coverage/
|
||||
.cache
|
||||
build/
|
||||
src/styles/unocss.css
|
||||
api/
|
||||
.next/
|
||||
.vercel/
|
||||
.cache/
|
||||
public/searchIndex
|
||||
7
apps/website/.prettierrc.cjs
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
...require('../../.prettierrc.json'),
|
||||
plugins: [
|
||||
'prettier-plugin-tailwindcss', // MUST come last
|
||||
],
|
||||
pluginSearchDirs: false,
|
||||
};
|
||||
190
apps/website/LICENSE
Normal 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.
|
||||