Compare commits

..

1918 Commits

Author SHA1 Message Date
iCrawl
8a7abc9f06 chore(Release): version upgrade 2020-11-26 00:03:06 +01:00
monbrey
a6b922f8ae fix(MessageReaction): set MessageReaction#me in patch method (#5047) 2020-11-25 23:57:03 +01:00
Amish Shah
5328648f45 fix(Voice*): filter out silent audio from video users (#5035) 2020-11-25 23:56:55 +01:00
izexi
f8b0c01c26 fix(GuildTemplate): 'guild' getter (#5040) 2020-11-25 23:56:41 +01:00
iCrawl
1f4b9fe749 chore(Release): version up 2020-11-22 14:03:20 +01:00
Matt (IPv4) Cowley
2a6c363a8a feat(Shard): shard-specific broadcastEval/fetchClientValues + shard Id util (#4991) 2020-11-22 13:35:18 +01:00
SpaceEEC
643f96c79b fix(Guild): fetch member if already in the guild (#4967) 2020-11-21 17:16:22 +01:00
izexi
2b2994badc feat: add support for guild templates (#4907)
Co-authored-by: Noel <buechler.noel@outlook.com>
2020-11-21 15:09:56 +01:00
SpaceEEC
eaecd0e8b7 fix(User): only assign to bot initially or if info is actually present (#4990) 2020-11-20 16:48:05 +01:00
SpaceEEC
2e940e635d fix(GuildMemberUpdate): cache incoming members & use partials if enabled (#4986)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-11-20 16:20:47 +01:00
SpaceEEC
8b91ac5d7e fix(MessageReaction*Action): correctly cache incoming members and users (#4969) 2020-11-20 16:19:18 +01:00
Sugden
7faa73a561 feat: add missing error codes (#5008)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-11-20 16:18:13 +01:00
Ashley Meadows
042e071a64 fix(MessageReaction): add client property to typings (#5003)
close #5002

Co-authored-by: Ashley Meadows <itsa-sh@users.noreply.github.com>
2020-11-17 22:05:03 +01:00
HarmoGlace
b8fd3f65d9 feat(Message): add crosspostable property (#4903)
Co-authored-by: Advaith <advaithj1@gmail.com>
Co-authored-by: Alex Hîncu <teesealz@gmail.com>
2020-11-01 12:32:20 +01:00
Christopher Bradshaw
efd7849ed0 docs: use npm ci instead of npm install (#4928)
Use `npm ci` instead of `npm install` after cloning the repository.
2020-11-01 12:30:25 +01:00
Matt (IPv4) Cowley
adf2e872f8 fix(Shard): don't pass event arguments to exit handler (#4957) 2020-11-01 12:29:29 +01:00
Matt (IPv4) Cowley
ed8b3cc9ea fix(PackageLock): reinstall GitHub docgen dev dependency (#4958) 2020-11-01 12:29:00 +01:00
iCrawl
7ec0bd93b0 chore(Release): version upgrade 2020-10-24 06:27:55 +02:00
monbrey
3d158f4448 fix(Action): attempt to get a User if GuildMember not returned (#4922) 2020-10-24 06:25:35 +02:00
Sugden
250c3ae3c1 fix(GuildChannel): parentID shouldn't be set in the constructor (#4919) 2020-10-19 22:24:18 +02:00
iCrawl
94c9cc2300 fix(Webpack): revert webpack upgrade 2020-10-19 18:46:49 +02:00
iCrawl
e9f36b5041 chore(Release): version upgrade 2020-10-19 18:27:26 +02:00
Souji
30808f9f0b feat(Message): allow custom emoji format for react (#4895) 2020-10-17 15:54:22 +02:00
Sugden
af670fc718 refactor: improve the accuracy of docs/improve docs (#4845)
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-10-17 15:53:02 +02:00
Jan
4bbe716aa0 fix(esm): add missing exports (#4911) 2020-10-17 15:47:56 +02:00
Jan
a7af4a8837 docs(PresenceData): add YouTube and remove application (#4910) 2020-10-17 15:47:49 +02:00
Noel
89feedad98 revert: "fix(GuildEmojiManager): check for guild in methods that use it" (#4912)
This reverts commit 728b3f939c.
2020-10-17 15:46:10 +02:00
Jan
728b3f939c fix(GuildEmojiManager): check for guild in methods that use it (#4886) 2020-10-17 15:40:39 +02:00
Sugden
7db6978012 fix(GuildMember): properly check permissions for hasPermissions (#4677) 2020-10-17 15:40:23 +02:00
Jiralite
6261dd65d3 fix(GuildEmojiCreate): Prevent double fire from emoji creation (#4863) 2020-10-17 15:40:04 +02:00
izexi
a45cc112e5 fix(GuildMemberManager): options.roles on 'prune' (#4838) 2020-10-17 15:39:29 +02:00
Constantinos
b8aa967226 ci: use npm ci instead of npm install (#4877)
Use npm ci instead of npm install when installing dependencies in CI.
2020-10-17 15:38:53 +02:00
Adrian Paschkowski
6e4308bfde fix(GuildChannel): Default parentID to null (#4881) 2020-10-17 15:36:16 +02:00
Adrian Paschkowski
dd12912124 fix(Actions): Avoid crash in InviteCreate with unknown channel (#4882) 2020-10-17 15:36:02 +02:00
Adrian Paschkowski
937153a92f fix(GuildMemberManager): Use actually random nonce in fetch (#4884)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2020-10-17 15:35:22 +02:00
Matt (IPv4) Cowley
c412cd7521 feat(Message): add messageEditHistoryMaxSize to limit stored msg edits (#4867) 2020-10-17 15:34:49 +02:00
cherryblossom000
4a6fb9a7d4 types(TextBasedChannel): make lastPinAt nullable (#4842)
This commit makes `TextBasedChannelFields#lastPinAt` nullable in the
typings.
2020-10-17 15:33:57 +02:00
cherryblossom000
824e92229d types(Activity): move flags from Presence to Activity (#4843)
This commit moves the `flags` property from `Presence` to `Activity` in
the typings.
2020-10-17 15:33:37 +02:00
Jiralite
0b59141054 types(GuildPreview): Make description nullable (#4854)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2020-10-17 15:33:08 +02:00
yuta0801
b9ad51049e fix(GuildChannel): make setTopic argument nullable (#4875) 2020-10-17 15:32:32 +02:00
Antonio Román
d2341654fe fix(Rest): resolved a regression, added retried AbortError (#4852) 2020-09-29 18:05:54 +02:00
Jan
169d4c3bff refactor(ReactionUserManager): use client property (#4829) 2020-09-25 23:46:31 +02:00
monbrey
13d64e6fa6 fix(MessageManager): throw if delete param is not MessageResolvable (#4825) 2020-09-25 23:46:06 +02:00
Jan
f83b3d7fc1 feat(NewsChannel): add support for following (#4805)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-09-25 23:45:47 +02:00
cherryblossom000
f2bbad36d5 feat(GuildManager): add AFK and system channel options in create (#4837)
This commit adds support for the `afk_channel_id`, `afk_timeout`, and
`system_channel_id` parameters in the
[create guild](https://discord.com/developers/docs/resources/guild#create-guild-json-params)
endpoint by adding the `afkChannelID`, `afkTimeout`, and
`systemChannelID` options in `GuildManager#create`.

This commit also fixes a minor bug in `create` when specifying types for
the channels due to the channel types not being changed from `'text'`,
`'voice'` etc to the corresponding numbers, so Discord would return an
error.
2020-09-25 23:44:32 +02:00
Matt (IPv4) Cowley
77c0788b2c fix(Shard): avoid caching null child in eval/fetchClientValue (#4823) 2020-09-25 23:43:32 +02:00
MrWasdennnoch
4e79e39e22 fix(Action): Sanity-Check if Discord includes all required data (#4841) 2020-09-25 23:42:49 +02:00
Antonio Román
32fe72f909 feat(Rest): switch queue to AsyncQueue (#4835)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-09-25 23:42:24 +02:00
Ryan Munro
1e63f3756e fix(Message): use Promise#reject instead of Throw on Message#delete (#4818) 2020-09-15 18:35:54 +02:00
MrWasdennnoch
8fa3a89482 fix(Action): Don't crash when partials are disabled (#4822) 2020-09-15 18:35:20 +02:00
Advaith
9c76129a23 feat(ActivityTypes): add Competing (type 5) (#4824) 2020-09-15 18:33:52 +02:00
Noel
01ceda5b0c chore(Deps): bl vulnerability (#4813) 2020-09-13 12:48:53 +02:00
MrWasdennnoch
eeb4c14754 fix(Partials): Use more user objects available from the gateway (#4791) 2020-09-13 12:09:12 +02:00
Johnson Chen
bcb7c721dc feat(Message): add support for crossposting (#4105)
Co-authored-by: Advaith <advaithj1@gmail.com>
Co-authored-by: Joe <56809242+Jo3-L@users.noreply.github.com>
Co-authored-by: Jan <66554238+Vaporox@users.noreply.github.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-09-13 12:07:56 +02:00
dependabot[bot]
0da65becd3 chore(deps): bump node-fetch from 2.6.0 to 2.6.1 (#4812)
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-13 11:57:44 +02:00
Sugden
422a4dda68 typings(Guild): document RELAY_ENABLED feature (#4788) 2020-09-08 09:58:56 +02:00
anandre
222137dcd1 docs(Role): Update various Role method descriptions (#4798)
Co-authored-by: Papaia <43409674+Papaia@users.noreply.github.com>
2020-09-08 09:58:11 +02:00
Quentin
372a405926 docs(ReactionCollector): Revise JSDoc for ReactionCollector#dispose and #remove (#4709)
Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
Co-authored-by: uhKevinMC <plainkevin123@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-09-08 09:57:39 +02:00
anandre
dfd63bdb6b docs(Guild): Guild.setName() example (#4797)
The docs example was incorrect, as the parameter is called `updated` but was later referenced as `guild`.  This PR fixes that by changing it to `updated` to match other examples, such as `setRegion()`
2020-09-05 20:18:00 +02:00
Papaia
5b39737d49 fix(lint): RESTManager warning (#4796)
Co-authored-by: Papaia <43409674+ItsPapaia@users.noreply.github.com>
2020-09-05 20:16:09 +02:00
cherryblossom000
904aecfdb7 types: don't use readonly arrays in interfaces (#4794)
This reverts some of the changes in f451be05 so that this works:

```ts
const embed: MessageEmbedOptions = {
  fields: [{
    // fixed stuff
  }],
};
if (/* condition */) {
  embed.fields.push({
    // conditional stuff
  });
}
```

See https://github.com/discordjs/discord.js/pull/4692#issuecomment-687252066.
2020-09-05 20:14:39 +02:00
MrWasdennnoch
a28754b892 fix(Typings): remove Partial types from some events (#4781) 2020-09-05 20:13:59 +02:00
Sugden
b43e742503 docs(GuildChannel): ThisType should be this (#4793) 2020-09-05 10:20:32 +02:00
Darqam
8ac25d37d9 docs(MessageManager): Update example for fetchPinned (#4785)
Example showed the method for channel and not messageManager
2020-09-04 20:19:51 +02:00
Souji
77b6a7d5bd fix(Util): throw token invalid for fetching rec. shard amount (#4779) 2020-09-04 12:51:15 +02:00
MrWasdennnoch
aa25608c52 typings(PartialUser): fix PartialUser remove deleted property (#4773) 2020-09-03 09:53:44 +02:00
Jan
b0ab37ddc0 feat(Channel): add isText() type guard (#4745) 2020-08-31 09:59:17 +02:00
Sugden
3141f7cb04 feat(Guild): add includeApplications option for fetchIntegrations (#4762) 2020-08-31 09:17:53 +02:00
Sugden
7ba9440053 fix(Guild): cache fetched widget data (#4760) 2020-08-31 09:16:53 +02:00
Sugden
f97316319f feat(UserFlags): add renamed UserFlags (#4761) 2020-08-30 00:34:37 +02:00
Tristan Guichaoua
405b487dc3 fix(Typing): change NodeJS.Timer into NodeJS.Timeout (#4755) 2020-08-29 18:54:39 +02:00
Tristan Guichaoua
b48b782c87 chore(Prettier): add settings for prettier plugin (#4756)
Co-authored-by: Papaia <43409674+Papaia@users.noreply.github.com>
2020-08-29 12:08:47 +02:00
cherryblossom000
74763ef3fb types: don't allow any object in the first parameter if second parameter is not given in TextBasedChannel#send (#4736) 2020-08-29 12:08:04 +02:00
Carter
74ebb650df style: remove unnecessary eslint comment (#4758) 2020-08-29 12:05:33 +02:00
Louis
a363b90fa5 docs(BaseGuildEmoji): account for optional properties (#4723) 2020-08-28 14:19:53 +02:00
Sugden
6aab9c3d64 fix: correctly import extendable classes (#4744) 2020-08-28 14:19:20 +02:00
Tristan Guichaoua
2dc70af717 types: add all types for GuildAuditLogsEntry#target (#4738)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-08-28 14:18:45 +02:00
Sugden
46acfac327 refactor(Client): remove non-existant property from toJSON (#4750) 2020-08-28 14:18:17 +02:00
Sugden
727b29c85d feat(Client): allow options for generateInvite (#4741) 2020-08-28 14:17:37 +02:00
Sugden
e0e271162c fix(typings): bot cannot be null (#4719) 2020-08-27 16:40:36 +02:00
InkoHX
cfc68677ee docs(ClientOptions): fix typo (#4730) 2020-08-27 16:39:55 +02:00
Noel
43c4d80b12 ci(CodeScanning): add CodeQL code scanning workflow 2020-08-24 19:27:00 +02:00
Carter
05c9e30163 docs(APIMessage): fix wording on comment (#4717) 2020-08-17 09:56:18 +02:00
Carter
b6167d8c3b docs: update jsdoc type for User#bot (#4716) 2020-08-17 09:45:57 +02:00
iCrawl
56e8ef2d38 chore(Release): version upgrade 2020-08-15 20:38:09 +02:00
Jan
db512d8f62 fix(User): set User#bot to false if not partial (#4706)
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-08-15 20:04:32 +02:00
Noel
5249cf33e5 revert(Shard): "fix missing child_process silent option of Shard to allow listening to output" (#4707)
This reverts commit 58d1589a55.
2020-08-15 12:50:05 +02:00
Jan
09bde74e43 chore: bump version in package-lock.json (#4705) 2020-08-15 12:38:40 +02:00
iCrawl
a4dbfdce59 chore(Release): version upgrade 2020-08-14 21:56:11 +02:00
Noel
dea48d64a5 chore(Deps): upgrade deps (#4701) 2020-08-14 21:46:23 +02:00
Advaith
178439ef8c feat: trigger userUpdate on GUILD_MEMBER_UPDATE (#4697) 2020-08-14 20:49:44 +02:00
Carter
f1194afd7c feat(GuildMemberManager#prune): roles query param (#4142)
Co-authored-by: izexi <43889168+izexi@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: kyranet <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-08-14 20:14:31 +02:00
Carter
2742923df4 feat(GuildManager): adds GuildManager#fetch (#4086)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-08-14 19:34:19 +02:00
Human
0b38c5d8b3 docs: updated applications URL (#4699) 2020-08-14 19:33:11 +02:00
cherryblossom000
f451be0519 feat(typings): use readonly arrays in parameters (#4692)
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-08-13 20:43:51 +02:00
Advaith
f991bd46f3 chore(Constants): update large_threshold default (#4698) 2020-08-13 20:38:59 +02:00
Quentin
139e56c774 docs(ReactionCollector): update remove and dispose events (#4136)
Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
Co-authored-by: uhKevinMC <plainkevin123@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-08-12 23:22:45 +02:00
Androz
e7eda72c9d feat(typings): add number type for setExplicitContentFilter method (#4694) 2020-08-12 23:18:58 +02:00
Sugden
980243f2d5 fix(Partials): correctly set properties as nullable (#4636) 2020-08-12 21:26:59 +02:00
Sugden
b6ddd4ce41 fix(APIMessage): add reply user to allowedMentions (#4591) 2020-08-12 21:25:38 +02:00
Arthur
6caeaeb391 fix(MessageReactionAdd): prevent double messageReactionAdd triggering (#4682)
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-08-12 21:24:45 +02:00
Carter
290938bf80 feat: bypass cache check with forceFetch param (#4592) 2020-08-12 21:23:04 +02:00
Souji
0225851e40 feat(BitField): add problematic bit to error (#4617) 2020-08-12 12:37:01 +02:00
Sardonyx
2a7f749d5a docs(Embeds): Added descriptions to the typedefs (#4303)
Co-authored-by: RDambrosio <rdambrosio016@gmail.com>
2020-08-12 12:29:02 +02:00
Advaith
57ca3d7843 feat(Guild): updates for Community guilds (#4377)
Co-authored-by: SpaceEEC <spaceeec@users.noreply.github.com>
2020-08-12 12:21:17 +02:00
Advaith
de8d26d791 docs(Constants): Improve large_threshold description (#3744)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-08-12 12:17:13 +02:00
Advaith
5be6630843 feat(Guild): discovery splash (#4619)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2020-08-12 11:09:18 +02:00
Advaith
446bbfe9eb docs(Ban): days must be 0-7 (#4693)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Noel <icrawltogo@gmail.com>
2020-08-12 09:35:33 +02:00
Tristan Guichaoua
f2f31a14c9 feat(types): BitFieldResolvable use ReadonlyArray (#4604) 2020-08-12 09:34:24 +02:00
Sugden
e92cbc444b feat: deprecate GuildEmbed methods and properties in favour of GuildWidget (#4121) 2020-08-12 09:33:00 +02:00
Advaith
baffbdb541 fix(Integration): user might not be present (#4691)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2020-08-12 09:30:34 +02:00
Bence
b7740d4859 feat(GuildEmoji): cache the author (#4334)
Co-authored-by: Papaia <43409674+Papaia@users.noreply.github.com>
2020-08-12 09:27:00 +02:00
Souji
599cde3627 fix(GuildChannel): make lockPermissions use parent overwrites (#4627)
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2020-08-12 09:23:31 +02:00
Advaith
bd2bb0e1c7 docs(Welcome): change discord badge to shields.io for consistency (#4633) 2020-08-12 09:22:44 +02:00
samsamson33
03580b23a3 feat(Util): add missing colors to docs (#3843)
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-08-11 23:40:07 +02:00
Jan
9d747d14c5 docs(Client): fix docs for login method (#4350) 2020-08-11 23:36:25 +02:00
Nathan Franke
124afeb843 fix(Collector): support async (#4123) 2020-08-11 23:34:47 +02:00
Hayden Andreyka
05cbf70486 docs(Guild): clarify vanity URL documentation (#4125)
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-08-11 23:05:03 +02:00
Jared Gesser
58d1589a55 fix missing child_process silent option of Shard to allow listening to output (#4308) 2020-08-11 23:01:19 +02:00
Sugden
49ad279c52 refactor(GuildMemberManager): use data instead of query (#4370) 2020-08-11 23:01:02 +02:00
Erwann Hilley
1fbaf8816e feat: add Blob support for browser (#4338)
Co-authored-by: Papaia <43409674+Papaia@users.noreply.github.com>
2020-08-11 23:00:12 +02:00
Souji
b4d651055a fix(BaseManager): properly type valueOf (#4594) 2020-08-11 22:59:44 +02:00
Sugden
c5b6c4da43 fix: correctly import VoiceState (#4616) 2020-08-11 22:59:03 +02:00
Jan
f628981f42 docs(CategoryChannel): Fix children being incorrectly marked as nullable (#4620) 2020-08-11 22:58:30 +02:00
Souji
a663ea4d2c fix(ApiMessage): respect allowedMentions with split (#4588) 2020-08-11 22:57:12 +02:00
Zaid - Nico
2be68e4125 fix(Message): Message#createdTimestamp uses deconstructed message id to get timestamp (#4632) 2020-08-11 21:02:15 +02:00
Souji
317f24076e fix(Util): support empty array for flatten (#4590) 2020-08-11 21:01:29 +02:00
Souji
fab3153de6 fix: consider #nsfw false if not present in data (#4593) 2020-08-11 21:00:29 +02:00
Souji
276dddcbfb fix(PresenceStatus): include invisible in typings (#4585) 2020-08-11 20:59:47 +02:00
Souvik
2adb5815bf fix: set #nickname to null as the default value (#4641) 2020-08-11 20:58:52 +02:00
tiehm
3df99930e8 fix(Typings): Channel#delete returns bad type (#4118) 2020-08-11 20:58:12 +02:00
Matthew Stead
e54c21bc65 feat(typings): TypeScript support for changing $browser (#4667) 2020-08-11 20:57:42 +02:00
Souji
bbfc715821 fix(Message): include MessageEmbed type (#4675) 2020-08-11 20:56:01 +02:00
Sanskar Jha
755f3798d1 docs(examples): fix example img (#4678) 2020-08-11 20:55:05 +02:00
Arthur
5b716c5b0c docs(ReactionManager): clarify cache Collection keys type (#4683) 2020-08-11 20:54:14 +02:00
Jan
b0e53e9c6d docs(Message): add NewsChannel type to Message#channel (#4680) 2020-08-11 20:53:29 +02:00
Androz
c55b5c8c19 fix(typings): correct spelling of APIError (#4687) 2020-08-11 20:52:10 +02:00
모메MoMe
fb1dd6b53a fix(Util): Fix cleanContent mention exploit (#4663) 2020-07-29 12:47:20 +02:00
Jan
0e61fca974 docs: make use of MessageResolvable type for bulkDelete (#4661) 2020-07-29 12:15:23 +02:00
camc
2b6e6d8631 feat(Module): add ReactionManager to exports (#4372)
add ReactionManager to the manager exports in src/index.js

closes #4363
2020-07-17 10:20:51 +02:00
Tenpi
47151fc2a9 fix(typings): allow custom events (#4162) 2020-07-17 10:17:44 +02:00
Souji
5027787aec chore: add relevant client options section to issue template (#4587) 2020-07-17 10:16:37 +02:00
Souji
c79ac4d9fc feat(Message): support pin and unpin with reason (#4586)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-07-17 10:13:30 +02:00
Souji
f9f3661090 fix(User): type dmChannel as nullable (#4609) 2020-07-06 19:07:33 +02:00
Crawl
ae716872b9 chore(deps): remove peer-deps as per npm@7 (#4272) 2020-06-19 11:48:01 +02:00
Phineas
ea19faa411 Change domain to discord.com (#4160) 2020-06-19 11:46:59 +02:00
Papaia
9a1c56c5b9 docs(erlpack): discordapp to discord (#4288)
Co-authored-by: Papaia <43409674+ItsPapaia@users.noreply.github.com>
2020-06-19 11:46:29 +02:00
Jan
214981f0b1 feat(MessageMentions): fix typings/docs, add resolvables support (#4339) 2020-06-19 11:43:19 +02:00
Souji
16847a3c13 fix: typing start event emitting on non text based channels (#4349) 2020-06-19 11:42:06 +02:00
uhKevinMC
54a7fdadda feat(voiceState): add self_video property (#4346) 2020-06-19 11:41:11 +02:00
Papaia
1c275afd7c fix(Guild): fix vanityURLUses desc, internally use fetchVanityData (#4335)
* docs(vanityURLUses): use fetchVanityData

* feat(fetchVanityCode): internally call fetchVanityData

* Update src/structures/Guild.js
2020-06-04 19:17:18 +02:00
Johnson Chen
8030612e52 feat(Guild): add fetchVanityData (#4103)
* chore: deprecate Guild.fetchVanityCode()

* feat: add Guild.fetchVanityData()

* chore: update typings

* fix: remove redundant .then()

Co-Authored-By: Antonio Román <kyradiscord@gmail.com>

* chore: fix lint

* chore: util.deprecate fetchVanityCode

* feat: add VanityData typedef and populate vanityURLUses

* chore: update typings

* chore: properly deprecate fetchVanityCode

* chore: fix jsdoc description for fetchVanityData

* feat: make fetchVanityData an async function

* chore: update Vanity typedef

* docs: update jsdoc

* feat: throw vanity url error instead of returning rejected promise

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* docs: disable max-len rule and add info about receiving parameter

* fix: throw Error instead of rejecting Promise

* revert: revert "fix: throw Error instead of rejecting Promise"

This reverts commit 7ffd53eba4.

* fix: require DJSError to fix throwing VANITY_URL error

* nitpick: re-add TypeError to the import

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

Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2020-06-04 13:41:20 +02:00
Carter
257371da28 feat(REST): allow options.query as URLSearchParams (#4143)
* feat: support query as URLSearchParams

* style: remove unnecessary comment

* patch: use const

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>

* feat: not reconstructing the search params

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-06-04 13:34:29 +02:00
nolan
5955498aca fix(DataResolver): resolveInviteCode to support new domain (#4281)
Update resolveInviteCode method to support "discord.com/invite" links.
2020-06-04 13:22:26 +02:00
Papaia
fc4bddf82a fix: grammatical errors in INVALID_TYPE errors (#4289)
* fix(GuildMemberRoleManager): grammatical error

* fix: eslint

* fix(GuildChannel): an

* fix(PermissionOverwrites): an

Co-authored-by: Papaia <43409674+ItsPapaia@users.noreply.github.com>
2020-06-04 13:02:28 +02:00
Souji
bd349650a7 docs(Guild): description of Guild#premiumSubscriptionCount (#4324) 2020-06-04 12:56:48 +02:00
Sugden
88a62d5fea docs(GuildManager): resolve returns a GuildChannel (#4333) 2020-06-04 12:52:43 +02:00
Evan
b0b62d63cf chore(docs): remove comment about type 13 (#4159) 2020-05-21 13:18:06 +02:00
Sugden
15b53509da fix(APIMessage): only pass allowedMentions if content is defined (#4269) 2020-05-21 13:17:00 +02:00
Schuyler Cebulskie
153a030c1f Improve text for Discord server link in issues 2020-05-17 02:51:28 -04:00
Papaia
2583ad5da7 docs(WebSocketShard): add missing properties (#4268) 2020-05-09 17:23:32 +02:00
SpaceEEC
a6510d6a61 revert "chore(docs): example for timeout in message.delete()" (#4167) 2020-05-07 23:39:45 +02:00
SpaceEEC
407bc77d34 fix: in/de-crement max listener for client events (#4168) 2020-05-07 23:39:23 +02:00
Alexander Kashev
766b91d306 docs(ShardingManager): fix typo in JSDoc (#4158)
Fix typo introduced in PR #4157 in the link to Node docs
2020-05-05 22:45:30 +02:00
anandre
b385aedf36 chore(docs): example for timeout in message.delete() (#4165) 2020-05-05 22:41:41 +02:00
Alexander Kashev
99612ba14d docs(ShardingManager): remove experimental status of Worker threads (#4157) 2020-05-04 13:08:52 +02:00
Kevin
ec0227a476 feat(GuildMemberManager): nonce and chunk_count for _fetchMany (#4130)
Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>
2020-05-04 12:48:33 +02:00
anandre
2617d3c9f3 docs(VoiceState): remove permissions required from description (#4156) 2020-05-04 12:46:58 +02:00
Carter
6367f603f6 typings: Add User#fetchFlags (#4138) 2020-05-01 14:45:14 +01:00
sillyfrog
d3c9384c9c fix(Voice): correctly set speaking data in the voice ssrcMap
Co-authored-by: Sillyfrog <sillyfrog@users.noreply.github.com>
2020-04-30 17:21:29 +01:00
Carter
026691702d feat(Guild#fetch): withCount param (#4111) 2020-04-27 09:05:39 +02:00
Corentin Poupry
605ee8587b fix(MessageEmbed): explicitly mark proxyIconURL as undefined (#4097) 2020-04-26 17:02:45 +02:00
Alon L
819e04a7ab fix(Typing): dmChannel bulkDelete (#4115)
Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-04-26 15:59:30 +02:00
Sugden
46b9e25190 typings(User): mark locale and flags as optional (#4127) 2020-04-26 15:58:53 +02:00
Nathan Franke
1726651c71 chore(tooling): include mention of commit convention (#4124) 2020-04-24 12:02:04 +02:00
Alon L
e3303ac3a2 fix(Typing): setSpeaking public (#4109) 2020-04-24 08:44:37 +01:00
Crawl
67a74c33e1 fix(Webpack): add Buffer polyfill in browser (#4102) 2020-04-20 21:15:26 +02:00
Papaia
97cbbb176b fix(Guild): name acronym (#4104) 2020-04-20 21:15:14 +02:00
RDambrosio
5af1a552bc fix(PacketHandler): guild members chunk packet handler should… (#4092) 2020-04-19 12:25:32 +02:00
SpaceEEC
97d23de247 fix(Typings): add optional Set<Snowflake> to shardReady event (#4099) 2020-04-19 12:24:58 +02:00
Souji
863a70918a docs(Message): add timeout to Message#delete example (#4090) 2020-04-18 12:16:19 +02:00
Jyguy
6fbaf0a036 fix(User): jsdoc for User#flags (#4094) 2020-04-18 12:15:30 +02:00
iCrawl
d827544fbd chore(Release): version 2020-04-17 12:58:26 +02:00
thepheer
12187efdbd feat(DataResolver): prefer streams over buffers (#4075)
* feat(DataResolver): prefer streams over buffers

* feat(DataResolver): add `resolveFileAsBuffer`

Add `resolveFileAsBuffer` to use it in `resolveImage` which still requires Buffers to work.

* fix(DataResolver): make sure `resolveFile` always returns a Promise

* refactor(DataResolver): use for-await-of

* fix(DataResolver): use forked form-data which supports custom streams

* fix(APIRequest): use forked form-data in code too

Co-authored-by: - <5144598+-@users.noreply.github.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-04-17 12:03:50 +02:00
Ryan Munro
7c6000c5e3 feat(ClientOptions): allow setting default allowedMentions (#4085)
* feat(ClientOptions): add default allowedMentions

* feat(ClientOptions): use default allowedMentions when not provided

* Update src/structures/APIMessage.js

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* Update src/structures/APIMessage.js

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* fix(ClientOptions): default allowedMentions should be undefined

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-04-17 11:23:31 +02:00
HarmoGlace
a88b7239b5 docs(RoleManager): everyone role can't be null (#3995)
* docs(RoleManager) : fix jsdoc everyone role can't be null

It fixes the jsdoc of RoleManager ; the everyone role of a guild can't be null

* Everyone role can't be null

* fix(typings): mark RoleManager#everyone as non-null

Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-04-16 12:18:43 +02:00
Duncan Sterken
0a3759f683 feat(ESModules): importing for esm modules (#3998)
* fix: importing for esm modules

* style: use single quotes

* refactor: remove 'use strict'
2020-04-16 12:11:24 +02:00
Sardonyx
da5d92812e docs(Webhook): id and token information (#3962)
* Documented how to get ID and Token of a webhook

* Update docs/examples/webhook.js

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* Explained whats the response body

* Update docs/examples/webhook.js

Co-Authored-By: Crawl <icrawltogo@gmail.com>

* Update docs/examples/webhook.js

Co-Authored-By: Crawl <icrawltogo@gmail.com>

* Update webhook.js

* Capitilized ID

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-04-16 12:09:26 +02:00
Kevin
ff3454ef89 feat(GuildMemberManager): customisable timeout for _fetchMany (#4081) 2020-04-16 12:07:32 +02:00
SpaceEEC
4625881c54 docs(MessageEmbed): document the constructor (#4077) 2020-04-16 12:07:08 +02:00
SpaceEEC
4c2308b4c6 docs(MessageManager): document return type of delete (#4012)
* docs(MessageManager): document return type of delete

* docs(MessageManager): use Promise<void> over Promise

Co-Authored-By: Papaia <43409674+ItsPapaia@users.noreply.github.com>

Co-authored-by: Papaia <43409674+ItsPapaia@users.noreply.github.com>
2020-04-16 11:57:03 +02:00
SpaceEEC
7ce58dbd4a docs(ShardClientUtil): link Shard#message from send method (#4028)
* docs(ShardClientUtil): link Shard#message from send method

* docs(ShardClientUtil): use @ emits instead of @ link
2020-04-16 11:56:42 +02:00
Ron B
2388467bd3 chore(Typings): stricter def for Client#emit (#4087) 2020-04-16 11:52:52 +02:00
withmask
d7096569c8 fix(PermissionOverwrites): resolveOverwriteOptions description (#4088)
smoll update
2020-04-16 11:52:06 +02:00
Advaith
fcacf1bc0d fix(Guild): sort text, news, and store channels together (#4070) 2020-04-16 10:35:19 +02:00
Carter
2e5a6476d5 feat: User#flags (#4060)
* feat: user flags

* fix: unnecessary negated statement

* fix: wording for description

* fix: an vs. a

* feat: add verified bot and dev flags

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* typings :verified bot and dev flags

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* feat: mon's suggestion, async fetchFlags & jsdoc

* feat: added to index.js

* fix: typo

* style: leveled flags

* typings: update leveled flags

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
2020-04-16 10:32:15 +02:00
cherryblossom000
72a33cb8c2 fix(Typings): GuildPreview#features and Integration#type (#4080)
* fix(Typings): make GuildPreview#features an array

* fix(Typings): make Integration#type a string
2020-04-16 10:31:40 +02:00
SpaceEEC
72a7f2b3ed fix(ClientApplication): type fetchAssets as resolving with an a… (#4078) 2020-04-16 09:27:52 +02:00
SpaceEEC
a8db9884d5 feat(Message): add allowedMentions to MessageEditOptions (#4071) 2020-04-16 09:27:19 +02:00
Roki
1330e2d246 feat: add supported 4096 image size and jpeg format (#4031)
* add 4096 avatar size that discord supports

* jpeg is also a thing

* update jsdocs

* update typings and remove duplicate type
2020-04-12 22:20:31 +02:00
Jyguy
9ba4eff279 fix(StreamDispatcher): correct property types (#4059)
* typings(StreamDispatcher): correct property types

* typings(StreamDispatcher): order methods alphabetically
2020-04-12 20:58:53 +02:00
Vlad Frangu
e5fac8c32f chore(WebSocketShard): log Discord requested reconnects (#4066) 2020-04-12 20:57:50 +02:00
Quentin
a07c3c2f94 fix(BaseManager): remove declaration of remove method (#4069)
The BaseManager#remove method doesn't exist, but was in the BaseManager typings.
2020-04-12 20:54:34 +02:00
SpaceEEC
828640ca26 ci(Testing): add TypeScript test job (#4002)
* ci(Testing): add TypeScript job

* chore: add eol before eof
2020-04-04 14:11:59 +02:00
SpaceEEC
9e4c39ae53 fix(Message): update MessageMention's roles on message edit (#4016) 2020-04-03 21:30:49 +02:00
Amish Shah
0e44ecd420 chore: fix typings/docs for VoiceBroadcast (#4014) 2020-04-03 11:19:24 +01:00
Advaith
849c6324d3 feat(Guild): PUBLIC_DISABLED and WELCOME_SCREEN_ENABLED features (#4009) 2020-04-03 11:59:51 +02:00
Syntle
691e96c5cf fix(Presence): add missing userID property to declarations (#4013)
* Added `userID` property to `Presence` class

userID property exists in docs but not in typings

* fix(Presence): userID should be typed as Snowflake

Co-Authored-By: BorgerKing <38166539+RDambrosio016@users.noreply.github.com>

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: BorgerKing <38166539+RDambrosio016@users.noreply.github.com>
2020-04-03 11:57:50 +02:00
iCrawl
6544d22338 chore(Release): version 2020-03-27 22:25:33 +01:00
SpaceEEC
5e491260a1 fix(Typings): use Channel instead of *ChannelTypes in ClientEve… (#4001) 2020-03-27 22:23:46 +01:00
iCrawl
f16a0790ca chore(release): version 2020-03-27 21:04:59 +01:00
SpaceEEC
b441469044 revert: channel unions (#3918 69d69f2) (#3978)
* revert: channel unions (#3918 69d69f25b9)

* fix: correct tslint:disable

* revert: keep the GuildChannel#setParent change

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-03-27 20:58:11 +01:00
SouSinner
88133d0d77 feat(GuildPreview): implement support for "preview" endpoint (#3965)
* feat(GuildPreview): method — fetchGuildPreview

* feat(GuildPreview): structure — GuildPreview

* feat(GuildPreview): update typings

* fix(GuildPreview): remove typedef for Features — already exists

* refactor(GuildPreview): update JSDocs & method

* feat(GuildPreview): implement DiscoverySplash function

* fix(GuildPreview): description & error handling for id

* fix(GuildPreview): misleading description, assign emojis correctly

* feat(GuildPreview): func DisplaySplash & GuildPreviewEmoji interface

* fix(Typings): satisfy TSLint

* fix(GuildPreview): toJSON - returns a value now

* feat(GuildPreview): add fetchPreview method on instance of Guild

* feat(GuildPreview): update typings

* fix: missing client constructor

* fix: typo in typings

* feat(BaseEmoji): implement BaseEmoji — parent for emoji instances

* feat(BaseEmoji): refactor - GuildEmoji extends BaseEmoji now

* feat(BaseEmoji): refactor - adjust emojis prop to BaseEmoji instance

* feat(BaseEmoji): not documented fully - GuildPreviewEmoji

* feat(BaseEmoji): update typings

* fix: remove duplicate typing properties - inherited

* fix: remove redundant methods & properties - inherited / already set

* fix: let -> const

* fix: typings - put BaseEmoji after BaseClient

* fix: remove _clone method  - redundant

* refactor(GuildPreview): emojis should be a collection

* refactor: rename base class, move relevant props there and expose roles

* fix(GuildPreview): update emojis in _patch

* fix(Typings): remove empty line, add Client#fetchGuildPreview

* feat: export GuildPreview

* fix(Typings): add GuildPreview#discoverSplash, icon, and splash

Co-authored-by: LxveFades <twitchisadeck@gmail.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-03-27 20:57:28 +01:00
Jyguy
fee9a218e8 docs(MessageMentionTypes): move possible values to description (#3990)
* docs(MessageMentionTypes): correct type

* docs(MessageMentionTypes): change role to roles

* docs(MessageMentionOptions): correct description to allow usage as an array

* remove unneeded part of description

Co-Authored-By: Ryan Munro <rsm999@uowmail.edu.au>

* docs: add DisableMentionType to remove literal string types

Co-authored-by: Ryan Munro <rsm999@uowmail.edu.au>
2020-03-27 20:54:27 +01:00
Carter
51ff5ddb64 chore: incorrect word in issue template (#3996) 2020-03-26 11:33:11 +01:00
didinele
65e8c92d7c fix(WebsocketShard): pass ignore ACK when Discord asks for a beat (#3993) 2020-03-25 12:55:20 +01:00
Ryan Munro
f2fdb93318 fix(Typings): client message event should not emit PartialMessa… (#3983)
* fix(Typings): client message event should not emit PartialMessage

* Update typings/index.d.ts

Co-Authored-By: Jyguy <jskekkx@gmail.com>

Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: Jyguy <jskekkx@gmail.com>
2020-03-23 08:36:27 +01:00
Sugden
5da734c3d4 typings: add back accidental removal (#3984) 2020-03-23 08:30:04 +01:00
Jyguy
993411d9fe docs(MessageReaction): fix jsdoc for count (#3980) 2020-03-22 20:09:31 +00:00
SpaceEEC
215740157b fix: always emit guildUnavailable when a guild becomes unavailable (#3975) 2020-03-21 11:31:34 +00:00
Crawl
645e09e859 chore(ci): buggy void return rule 2020-03-21 09:54:58 +01:00
C eq Q divided-by U
495cfa96c2 fix(TypingStart): typing methods returning falsy values (#3939)
* fix: typing methods returning falsy values

* fix: eslint

* fix: no provided parameters; updated jsdocs

* fix(Typings): reflect typingStop

* refactor: since and lastTimestamp merged into one constructable value

* feat(Typings): document Channel#_typing

* feat: emit TypingData on typingStart; update jsdocs

* feat(Typings): move _typing to TextBasedChannel; sort props alphabetic

* feat(Event): remove typingStop

* feat(Typings): update typings - remove typingStop

* feat(Event): remove typingStop from Constants

* feat(Typing): remove TypingData class - redundant

* refactor(Events): remove TYPING_STOP event

* refactor(TypingData): now is an interface for _typing

* fix(TypingStart): timeout variable, removed emit for TypingData

* feat(Typing): timeout property on Channel#_typing, remove redundancy

* fix(Typings): extra overload(s)

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* Update index.d.ts

* fix(Typings): remove "private" from interface — invalid TS

* feat(Typings): add PartialUser in case partials are enabled

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* feat(Typings): document 'timeout' property of TypingData

Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-03-21 09:52:40 +01:00
Advaith
0f38d807c7 fix(Guild): default max presences value (#3970) 2020-03-21 09:02:12 +01:00
Ryan Munro
df324e2c21 feat(AllowedMentions): add support for MessageOptions#allowedMe… (#3893)
* feat(Allowed Mentions): Add support for new Allowed Mentions message options

* fix(docs): Update JSDoc for feature

* fix(apimessage): translate the propery into snake_case

* fix(typings): message mention options should be optional

* fix(docs): jsdoc typings for MessageMentionOptions

* fix(mentions): use Resolvables for MessageMentionOptions

* fix(docs): typedef for MessageMentionTypes

* Update typings/index.d.ts

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* fix(mentions): drop support for Resolvables

* fix(AllowedMentions): remove the whole resolve function

* fix(docs): revert change to Resolvables

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-03-19 11:56:03 +01:00
uhKevinMC
cd52424fb7 docs(VoiceState): improve phrasing of setChannel method (#3959)
* (docs) Fixed phrasing of docs

Added permission needed to edit a member's voice state and adjusted docs to say **"Disconnect"** instead of **"Kicking"** the member.

* fixed line length on 156
2020-03-19 11:51:40 +01:00
KhaaZ
5b9cdc5cd2 feat(Permissions): Adds VIEW_GUILD_INSIGHTS (#3928) 2020-03-17 21:37:40 +00:00
Sugden
a6605155f0 typings/fix(Partials): fix unexpected TSC errors (#3957) 2020-03-17 20:01:26 +01:00
Sugden
a5267e1163 docs(MessageEmbed): correct description of createdAt (#3897)
* docs(MessageEmbed): correct description of createdAt

* typo
2020-03-17 19:04:46 +01:00
Sugden
8b906c69bb fix(Partials): correctly document properties for partialized st… (#3922)
* fix(Partials): properly document partial properties

* style: turn tabs into spaces

* style: order properties alphabetically

* fix(typings): PartialDMChannel will always have a recipient

* change properties to undefined instead of null

* docs: correctly mark properties

* style: remove tabs

* fix(partials): document properties properly

* style: tabs

* style: random line

* docs(User): tag is nullable

* typings(User/GuildMember): document lastMessageID properly

* typings/fix: change lastMessageID to lastMessageChannelID

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-03-17 18:59:47 +01:00
izexi
8c0a940cdb fix(Channel): ensure partial DMChannels get created (#3954) 2020-03-17 18:52:59 +01:00
izexi
a36a65b36a fix(MessageReaction): fetching a removed partial custom emoji (#3955)
* fix: handling GuildEmoji within fetch()

* refactor: remove unused "private" methods

* refactor: make use of Message#fetch() to patch
2020-03-17 18:52:43 +01:00
Daniell
2be9ebaad2 feat(typings): allow event listener type param inference (#3944)
* feat: allow listener type param inference

* fix: typo

* fix: invalid listener type

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* fix: intellisense (user should extend interface)

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-03-17 18:52:11 +01:00
Crawl
7994b5612a docs(PlayInterface): update example for broadcast
Co-authored-by: Carter <45381083+Fyko@users.noreply.github.com>
2020-03-17 09:13:19 +01:00
SpaceEEC
7b38f46caf fix(RequestHandler): a global timeout implies limited (#3950) 2020-03-17 09:02:51 +01:00
Joe Villegas
609a545131 typings(StreamDispatcher): remove end event (#3945) 2020-03-17 09:02:43 +01:00
Sugden
a53404fac3 typings(PartialTextBasedChannelFields): fix send overload (#3942) 2020-03-15 19:14:10 +01:00
Ryan Munro
69d69f25b9 feat(Types): support type-guarding using Channel#type string li… (#3918)
* feat(types): union type for Channels

* feat(Types): union for TextBasedChannelTypes

* fix(Types): use new union types in return values

* Update typings/index.d.ts

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* Update typings/index.d.ts

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* fix(Types): various minor improvements for Partials

* fix(GuildChannel): partial should return false

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-03-14 16:50:43 +01:00
Sugden
44ac5fe6df fix(Util): cleanContent should remove mentions after formatting… (#3936) 2020-03-14 13:39:54 +01:00
Sugden
d43f78c845 typings(PartialTextBasedChannelFields): fix send overloads (#3935)
* typings(PartialTextBasedChannelFields): Remove duplicate types for parameters

* typings(PartialTextBasedChannelFields): fix overloads for send

* style: add semicolons and remove whitespace
2020-03-14 13:39:22 +01:00
vzwGrey
e5264aba37 fix(GuildMemberRolesManager): type error should mention Role an… (#3931)
* fix(GuildMemberRoleManager): type error should mention that Role or Snowflake are fine too

* fix(GuildMemberRoleManager): comma instead of 'or'

* style: break long line
2020-03-14 13:38:51 +01:00
SpaceEEC
ca75eb509a fix(GuildEmojiManager): throw an error if image resolving fails (#3934)
* fix(GuildEmojiManager): throw an error if image resolving fails

* refactor(GuildEmojiManager): remove redundant if branch
2020-03-14 11:44:08 +01:00
Sugden
5b8f02243c typings(Client): remove typingStop event (#3919) 2020-03-14 11:41:05 +01:00
iCrawl
76634db9be chore: use cross-env to set env vars 2020-03-08 20:18:40 +01:00
iCrawl
36050d07f5 chore: release version 12.0.2 2020-03-08 20:06:30 +01:00
SpaceEEC
a4f7e07b3b fix(APIRequest): only use form data when actually sending files (#3917) 2020-03-08 19:28:19 +01:00
Bence
79a28b55a8 docs(Structures): add ExtendableStructure typedef (#3908)
* docs(Structures): add ExtendableStructure typedef

* revert automatical package.json change
2020-03-08 19:28:03 +01:00
Crawl
b5dfb55923 docs: make collections more accessible in docs (#3907)
Fixes #3896
2020-03-08 19:27:42 +01:00
SpaceEEC
69d415301d perf(VoiceConnection): skip redundant volume transformer on join (#3916) 2020-03-08 17:40:06 +00:00
Matt (IPv4) Cowley
3e169cb4d3 fix(MessageEmbed): skip validation of fields when inside a message (#3894)
* fix(MessageEmbed): Add skipValidation flag to MessageEmbed

* fix(MessageEmbed): Use skipValidation flag in Message

* fix(MessageEmbed): Restore static normalizeField(s) methods

* fix(MessageEmbed): Update typings for constructor

* fix(MessageEmbed): Remove private docstrings/typings

* fix(MessageEmbed): Use skipValidation without storing in instance

* fix(MessageEmbed): skipValidation without modifying normalizeFields

* fix(MessageEmbed): Revert indentation change in typings

* fix(MessageEmbed): Clone logic from normalizeFields (duplicated code ftw)

* revert(MessageEmbed): remove dead code / breaking change

- dead code
  discord.js does not use those methods interally and won't in the future, as Discord
  does not emit any partial embed updates and doing so in the future seems unlikely.
- a breaking change (an incompatible api change)
  Although it's not recommended to do, users can modify
  received embeds without cloning them, e.g.:
  const embed = message.embeds[0].addField('some title', '');
  (replace '' with some function call; this is just an example)
  This would no longer throw a synchronous error (breaking change),
  but at a later point when actually sending it. (poorer to debug)

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-03-08 17:24:18 +01:00
Silver Shadow
3c653aafe8 docs(GuildMemberResolvable): an member -> a member (#3909)
an member -> a member
2020-03-08 16:00:43 +01:00
SpaceEEC
f387337787 fix(Guild): resolve role id and call existing handler (#3904) 2020-03-07 06:06:58 +01:00
Sugden
9b5f005394 test: update tests (#3865)
* test: update tests

* style: fix indent

* test: suggested changes

* test: require correct directory

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-03-07 06:05:57 +01:00
SpaceEEC
bca4b038a5 docs(BitField): document constructors of deriving classes (#3903) 2020-03-07 06:00:48 +01:00
Spooder
b5a7e5cdf0 docs(sharding): ShardingManager#createShard doesn't spawn the s… (#3875)
* Fixed createShard() to show an example!

* docs(ShardingManager): clarify createdShard docs

* docs(Shard): clarify manager parameter

* docs(ShardingManager): use an info tag for createShard's param

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-03-07 06:00:11 +01:00
Souji
61ef46ff30 fix: adapt #manageable to check for CONNECT for VoiceChannel (#3885) 2020-03-06 07:00:49 +01:00
iCrawl
0066d0089e chore: pascal-case in scope 2020-03-04 20:33:18 +01:00
Advaith
bfcd4befc9 docs(faq): replace ffmpeg-binaries with ffmpeg-static (#3886) 2020-03-03 12:29:56 +00:00
Amish Shah
11f30ccb31 v12.0.1 2020-03-01 22:33:21 +00:00
Jisagi
66e625c4c0 fix(guild): VerificationLevels (#3873) 2020-03-01 21:28:03 +01:00
SpaceEEC
cd746f3069 fix(message_mentions): lazy require GuildMember to avoid circular (#3877) 2020-03-01 20:27:47 +00:00
Crawl
1336156799 chore(ci): deploy docs for tags (#3878) 2020-03-01 21:25:29 +01:00
Amish Shah
2338594030 Merge branch 'master' into stable 2020-03-01 18:02:24 +00:00
Amish Shah
3142d8cf18 v12.0.0 2020-03-01 18:01:39 +00:00
Amish Shah
a133768618 v12.0.0 2020-03-01 18:00:39 +00:00
Amish Shah
7d40c43ad4 chore: merge v12-dev master into stable 2020-03-01 17:57:30 +00:00
Amish Shah
d7c5baf7f3 chore: update discordjs/discord.js references 2020-03-01 17:38:25 +00:00
Saya
f4b1b398d9 feat: document intent error code messages (#3871)
* Add 4013, Invalid Intents close code

* Add 4014, Disallowed Intents Code

* Add error messages for 4013 & 4014

* Rephrase invalid & disallowed intent error message

* Rephrase disallowed intent error message
2020-03-01 17:21:48 +00:00
Souji
2d67fbb24c docs: clarify which checks GuildMember#manageable does (#3870) 2020-03-01 15:11:06 +01:00
SpaceEEC
544bb78c8b refactor: make LimitedCollection an implementation detail (#3872) 2020-03-01 15:10:55 +01:00
Sugden
c7f4485cec docs(PartialRoleData): id is optional (#3866) 2020-03-01 15:10:46 +01:00
SpaceEEC
d72172744e v11.6.1 2020-02-29 19:13:53 +01:00
Anish Shobith P S
34d352dcbe docs: bump version to 11.6.0 (#3863)
* docs: Bump version to 11.6.0

* fix: typo
2020-02-29 19:11:42 +01:00
SpaceEEC
713309e7bb fix(playinterface): lazy require VoiceBroadcast to avoid circul… (#3864) 2020-02-29 19:07:23 +01:00
Souji
acdd832fe2 fix(typings): enum values for ChannelType (#3861) 2020-02-29 18:58:20 +01:00
Souji
09e4912a90 fix(typings): remove duplicate VerificationLevels (#3862) 2020-02-29 18:58:11 +01:00
Souji
a6d3501ff8 fix(typings): for intents (#3860)
* re-introduce Intents export
* properly type WebsocketOptions#intents
2020-02-29 18:18:59 +01:00
SpaceEEC
b3931eaebb v11.6.0 2020-02-29 15:28:37 +01:00
SpaceEEC
08e7328b86 docs(readme): remove mention of uws 2020-02-29 15:26:27 +01:00
Souji
8a2f8938be feat: Intents bitfield (#3844)
* feat: Intents bitfield

* suggestion: properly construct Intents.ALL

* fix: actually document the ws option

* suggestion: remove disabledEvents in favor of intents

* suggestion: remove obsolete check, validate falsy values

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* fix: GUILD_BANS flag

* fix: exception for intents check in ws options

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* docs: IntentsResolvable

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* Update Client.js

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-02-29 15:20:15 +01:00
iCrawl
b58813ace8 chore(*): update node version mention & use strict 2020-02-29 15:19:37 +01:00
didinele
d33fc741e3 typings: Refactor how channel types are done (#3808)
* refactor channel types

* really weird solution to make what the PR promises possible, I might revert this

* undo the dumb attempt

* Update index.d.ts

* fix GuildCreateChannelOptions#type

* fix(typings): remove initializers from the enum

* Update index.d.ts

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-02-29 15:11:56 +01:00
Sugden
a04b4cae3e docs(TextBasedChannel): fix typo (#3858) 2020-02-29 15:11:06 +01:00
SpaceEEC
31ee0d84d5 docs(shard): add .cache to GuildManager in fetchClientValue exa… (#3857) 2020-02-29 15:10:47 +01:00
iCrawl
d9e12b8bc2 fix(guild): import paths 2020-02-29 14:40:13 +01:00
Crawl
c065156a88 chore: consistency/prettier (#3852)
* chore: consistency/prettier

* chore: rebase

* chore: rebase

* chore: include typings

* fix: include typings file in prettier lint-staged
2020-02-29 14:35:57 +01:00
Ryan Munro
6650d50a56 feat(MessageEmbed): Support EmbedFieldData[] instead of EmbedFi… (#3845)
* fix(typings): MessageEmbedOptions#fields should be EmbedFieldData[]

* feat(MessageEmbed): Allow optional EmbedFieldData#inline in constructor

* docs(MessageEmbed): revert type change of fields

Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-29 14:21:43 +01:00
Papa
9c8aaf1bbc feat: reimplement disableEveryone into disableMentions
* User input sanitation: reimplement disableEveryone into disableMentions

* Change default value of ClientOptions#disableMentions to 'none'

* Update type declarations of disableMentions to include default

* update for compliance with ESLint

* Overlooked these files. Updated for complete compliance with ESLint
2020-02-29 14:20:39 +01:00
Bence
bbe169deac fix(MessageEmbed): prevent possible destructuring error 2020-02-29 14:19:56 +01:00
Sugden
e4f567c65e refactor(GuildChannel): change overwritePermisions to accept an… (#3853)
* refactor(GuildChannel): change overwritePermisions to no longer accept an object

* fix: check for instanceof Collection too
2020-02-29 14:19:21 +01:00
Sugden
f95df6f7d7 fix(Shard): cleanup after settling spawn promise (#3799)
* clear sharding ready timeout

* fix oops

* update typings

* commited to the wrong branch

* fix(Shard): cleanup after settling the spawn promise

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-29 14:18:57 +01:00
izexi
de4b4a0939 feat(GuildMemberStore): add options.withPresences to fetch() (#3562)
* feat: add options.withPresences to fetch()

feat: update presences if present on received data

typings: add user & withPresences to FetchMembersOptions

fix: checking for added options

ref: qol changes to return type

so that all members are fetched

oopsie

* fix: use Manager.cache

* fix(typings): tslint error

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-02-29 14:18:37 +01:00
Sugden
2ee0f1cdc6 feat(GuildManager): Allow for more options for GuildManager.cre… (#3742)
* typings: add GuildVerificationLevel and GuildExplicitContentFilter

* implement new types

* fix jsdoc on stores

* typo

* add more options for GuildStore#create

* add channels and roles

* update typings

* fix typings and use snake case for permissionOverwrites

* typings & jsdoc

* fix tslint

* remove trailing whitespace

* fix jsdoc

* fix jsdoc

* fix oopsies

* fix lint

* fix lint

* fix mr lint man

* add typedefs and support for setting channel parents

* fix tab indenation

* update jsdoc

* suggested changes

* style: fix silly format

* docs(PartialChannelData): name is not optional

* style: remove silly format
2020-02-29 07:43:42 +01:00
SpaceEEC
97457e1de2 feat(RichEmbed): add toJSON returning an api-compatible object
This backports:
PR: https://github.com/discordjs/discord.js/pull/3813
Commit: 4ec01ddef5
2020-02-28 18:29:41 +01:00
Sugden
3d0c1df19d refactor(Guild)/fix(Util): use resolveID and regex for cleanCod… (#3837)
* refactor(Guild): use resolveID instead of resolve(...).id

* fix(Util): use regex for cleanCodeBlockContent
2020-02-28 18:26:37 +01:00
Souji
6eaf63fb7c feat(RichEmbed): backport spliceFields and normalizeField (#3762)
* backport: RichEmbed#checkField, Util#resolveString

* backport: RichEmbed#spliceFields

* fix: typo

* chore: use util.resolveString everywhere

* chore: rename EmbedFIeld to EmbedFieldData

* consistency with v12

* chore: rename checkField to normalizeField

* consistency with v12

* fix: EmbedField instead of EmbedFieldData

* fix(typings): EmbedFIeld#inline is guaranteed

* fix(docs): add JSDocs typedef for EmbedFieldData

* fix(typings): EmbedFIeldData#name/#value

* should be StringResolvable

* refactor(RichEmbed): do not duplicate field prop checking

* docs(RichEmbed): document default for inline

* fix(RichEmbed): pass correct parameters to normalizeField

* typings(RichEmbed): add missing spaces

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-28 18:16:19 +01:00
Sugden
1af1e0cbb8 refactor: add some more consistency (#3842)
* cleanup(StreamDispatcher): remove old 'end' event

* fix(StreamDispatcher): only listen to finish event once

* refactor(VoiceWebSocket): use `connection.client` in favour of `connection.voiceManager.client`

* fix(VoiceWebSocket): use `client.clearInterval` in favour of `clearInterval`

* refactor: destructure EventEmitter

* refactor: destructure EventEmitter from events

* refactor: use EventEmitter.off in favour of EventEmitter.removeListener

* style: order typings alphabetically

* oops

* fix indent

* style: alphabetically organize imports

* style: remove extra line

* Revert "style: remove extra line"

This reverts commit 96e182ed69.

* Revert "style: alphabetically organize imports"

This reverts commit 02aee9b06d.

* Revert "refactor: destructure EventEmitter from events"

This reverts commit 9953b4d267.

* Revert "refactor: destructure EventEmitter"

This reverts commit 930d7751ab.

* Revert "fix(StreamDispatcher): only listen to finish event once"

This reverts commit 485a6430a8.

* refactor: use .removeListener instead of .off
2020-02-28 18:02:51 +01:00
Souji
df88729c44 feat(MessageEmbed): re-introduce MessageEmbed#addField (#3850)
* feat(MessageEmbed): re-introduce MessageEmbed#addField

* suggestion: sorting alphabetically

* suggestion: document inline to default false for #addField
2020-02-28 17:58:52 +01:00
Crawl
261816dcf8 chore(githooks): commitlint (#3836) 2020-02-28 17:43:45 +01:00
Sugden
31a3a86ebc docs(MessageEmbed): document article embed type (#3846) 2020-02-28 17:43:11 +01:00
Sugden
6109669c97 typings(WebhookClient): client is not a client (#3838) 2020-02-28 17:41:12 +01:00
Amish Shah
653784b564 chore(StreamDispatcher): remove end event
use finish event instead
2020-02-26 20:00:48 +00:00
Timo
9cb306c823 feat: replace disableEveryone with disableMentions (#3830)
* add ClientOptions#disableMentions and MessageOptions#disableMentions

* provide tests

* don't sanitize controlled mentions

* add @here mentions to tests

* fix indents (6 spaces instead of 8)

* add Util#cleanContent tests

* add typings for removeMentions

* replace @ with @\u200b AFTER cleaning content as suggested instead of using removeMentions

* better explanation of this option

* no newline in Util.removeMentions

* fix long line

* remove double space

* remove comments (change has been reverted)

* Use Util.removeMentions to remove mentions

* use Util.removeMentions in Util.cleanContent
2020-02-26 11:13:23 +00:00
Ryan Munro
cf646b5394 fix(typings): MessageOptions#split (#3834) 2020-02-26 09:46:19 +01:00
Crawl
c4bda746c8 chore(githooks): husky (#3835) 2020-02-24 23:32:12 +01:00
Crawl
3a0470b45c chore(deps): update deps and fix lint (#3833) 2020-02-24 23:14:31 +01:00
Crawl
c1d396a6c4 Partial-revert "typings(WebhookClient): client is not a Client" (#3831)
* Revert "typings(WebhookClient): client is not a Client (#3829)"

This reverts commit 44ff67dc11.

* Update index.d.ts

* Update index.d.ts
2020-02-24 22:44:46 +01:00
Sugden
44ff67dc11 typings(WebhookClient): client is not a Client (#3829)
* typings(WebhookClient): client is not a Client

* style: use tabs
2020-02-24 22:01:41 +01:00
Sugden
91a025caaa feat: GuildEmoji & Invite to GuildResolvable (#3637)
* Add GuildEmoji to GuildResolvable

* Add GuildEmoji to GuildResolvable

* Add Invite to GuildResolvable

* Add Invite to GuildResolvable

* oops

* oops x2

* Add Guild#fetchBan and an error for not resolving the ID

* typings

* Revert "Add Guild#fetchBan and an error for not resolving the ID"

This reverts commit a4d0ed16e7.

* Revert "typings"

This reverts commit 5a54e88785.

* fix jsdoc

* add trailing comma
2020-02-24 18:27:34 +01:00
Sugden
02807347e7 fix: Client#sweepMessages should throw an INVALID_TYPE error (#3828)
* fix(Client): sweepMessages shouldn't shrow an invalid client option error

* style: trailing commas
2020-02-24 18:27:15 +01:00
BorgerKing
52c0a4067b fix(MessageEmbed): various typos and fixes (#3819)
* fix: typo

* fix: couple more typos

* fix: grammar stuff

* fix: EmbedField takes StringResolvable not string

* Revert "fix: EmbedField takes StringResolvable not string"

This reverts commit c1bdd78ad3.

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-02-24 18:21:29 +01:00
matthewfripp
acf724e691 feat(Collector): Addition of resetTimer() (#3825)
* feat(Collector): Addition of resetTimer()

* typings
2020-02-24 18:17:24 +01:00
SpaceEEC
a69ebbe9d9 feat/fix(GuildAuditLogs): handle new event types (#3602)
* feat/fix(GuildAuditLogs): handle new event types

* fix(GuildAuditLogsEntry): coerce to numbers, simplify extra for deleted entities

* fix(GuildAuditLogsEntry): do not revert 'type' extra
2020-02-24 18:16:20 +01:00
Sugden
0a1b9a5285 refactor: remove unused error in catch statements (#3820)
* refactor(handlers): remove unused error in catch

* refactor(PacketHandler): remove unused error

* refactor(SecretBox): remove unused error

* refactor(ClientPresence): remove unused error

* style: remove space

Co-Authored-By: Crawl <icrawltogo@gmail.com>

Co-authored-by: Crawl <icrawltogo@gmail.com>
2020-02-24 18:15:38 +01:00
Crawl
98a552107e tooling(typings): new linter for typings (#3827) 2020-02-24 17:56:44 +01:00
Crawl
e6d22527bb chore(typings): semicolon consistency (#3826) 2020-02-24 17:22:16 +01:00
Souji
54f24d1fea typings(MessageEmebd): fix typings for addFields (#3821)
* typings(MessageEmebd): fix typings for addFields

* fix: add missing semicolon

* docs(MessageEmbed): fix various types

* in accordance with the scope of the PR

* Update src/structures/MessageEmbed.js

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-24 14:02:06 +01:00
Sugden
967b533e9d typings(MessageEmbed): properly mark properties (#3822)
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-24 13:06:22 +01:00
Sugden
25cd23e305 cleanup(DMChannel): remove _cacheMessage (#3824)
* cleanup(DMChannel): remove _cacheMessage

* update actions/checkout to v2

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-24 13:06:00 +01:00
SpaceEEC
d406f42ce0 docs/typings(SystemChannelFlags): properly document and use resolvable (#3794)
- Change GuildEditData#systemChannelFlags to use SystemChannelFlagsResolvable
- Move SystemChannelFlagsResolvable outside of class definition to make the docs generator happy
2020-02-24 13:03:45 +01:00
SpaceEEC
ccb83a71ee docs/typings(MessageAttachment): mark spoiler as readonly, order spoiler in typings (#3714) 2020-02-24 13:03:02 +01:00
Tenpi
e57ef25082 typings/fix(MessageEmbed): add interfaces for props, fix copy constructor (#3492)
* updated typings

* Updated docs

* fixed types for MessageEmbedOptions

* added curly bracket spaces

* fix(MessageEmbed): make copy constructor work properly

* fix(MessageEmbed): copy the provider too

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-24 11:44:54 +01:00
Sugden
28490e84b0 typings(Invite): channel can be a PartialGroupDMChannel (#3823) 2020-02-24 10:41:29 +01:00
SpaceEEC
4ec01ddef5 feat(MessageEmbed): change toJSON method to return an api-compatible object (#3813) 2020-02-23 20:42:47 +01:00
Souji
b727f6c1b9 feat: bring embed builder field manipulation in line with underlying array functionality (#3761)
* feat: splice multiple fields

* remove MessageEmbed#spliceField
* add MessageEmbed#spliceFields
* to behave more like Array#splice
* and allow multiple fields to be replaced/inserted
* update typings accordingly

* refactor: rename check to normalize

* check suggests boolean return type

* feat: allow spread args or array as field input

* rewrite: replace addField in favor of addFields

* typings: account for changes

* chore: bump min node to 11.0.0

* for Array#flat

* fix: bump min-node in package engines field

* remove addBlankField
2020-02-23 20:41:48 +01:00
Sugden
ecd8cccddf typings(AddGuildMemberOptions): change accessToken from String to string (#3815) 2020-02-23 09:16:20 +01:00
iBisho
b347e9ec26 refactor(MessageEmbed): simplify initialization of files property (#3814) 2020-02-22 22:36:29 +01:00
Sugden
161f90761a feat(PartialGroupDMChannel): to support Invite#channel for group dms (#3786)
* add PartialGroupDMChannel class

* fix lint

* add new errors

* add new class to Channel.create

* fix lint

* update typings accordingly

* better implement errors

* remove unnecessary functions

* oops

* lint

* lint

* lint

* more lint

* more lint

* jsdoc typo

* suggested changes

* i did not forget the typings
2020-02-22 13:25:27 +01:00
Sugden
b0aed050e3 feat(Guild): add rulesChannel and publicUpdatesChannel (#3810)
* add rulesChannel* & publicUpdatesChannel*

* update typings
2020-02-22 13:14:11 +01:00
Sugden
bea6da621d feat(Guild): add rulesChannel and publicUpdatesChannel (#3810)
* add rulesChannel* & publicUpdatesChannel*

* update typings
2020-02-22 13:04:41 +01:00
Sugden
b0d0b81c61 feat: add new MessageTypes (14 and 15) (#3812)
* document types

* typings

* move comment
2020-02-22 12:52:31 +01:00
SpaceEEC
7e9c995566 feat(Message*): add missing fields, add support for flag editing (#3795) 2020-02-22 12:38:43 +01:00
SpaceEEC
330c410796 feat(Guild): add support for system channel flags (#3793) 2020-02-22 12:36:59 +01:00
SpaceEEC
ab866d6b2e feat(GuildChannel): add support for clone options, deprecate old signature (#3792) 2020-02-22 12:35:22 +01:00
Sugden
ef8acecc70 feat: add new MessageTypes (14 and 15) (#3812)
* document types

* typings

* move comment
2020-02-22 12:31:51 +01:00
Souji
f6075a6e3a typings(Constants): add VerificationLevels (#3811) 2020-02-21 21:48:08 +01:00
Sugden
f85230812f typings(Guild): mark afkChannel* & applicationID as nullable (#3805) 2020-02-19 21:34:26 +01:00
Sugden
c4c6ad4a63 docs/typings(WSEvents): add missing, remove duplicated and userbot events (#3800)
- Added `MESSAGE_REACTION_REMOVE_ALL`
- Remove duplicated `VOICE_STATE_UPDATE`
- Remove userbot `USER_SETTINGS_UPDATE`
2020-02-17 14:15:59 +01:00
Vlad Frangu
e4e977f447 src: update client options and shards value if fetching shard count (#3787)
* src: Update client options and shards value if fetching shard count

* src: Fix bug and remove more dead code
2020-02-16 19:41:37 +01:00
Vlad Frangu
46ee06b424 feat(Message): add support for flag editing / embed suppression (#3674) 2020-02-16 19:36:10 +01:00
Sugden
bc5e2950d0 fix(ReactionManager): update message if partial (#3789)
* update message after fetching if it is partial

* suggested changes

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-16 19:24:12 +01:00
SpaceEEC
544b14a5ed docs(PermissionResolvable): move definition outside of class
Otherwise it won't appear in the docs for some reason
2020-02-16 13:05:47 +01:00
Vlad Frangu
21d37ed0cc docs: clarify what zlib-sync does (#3785)
* docs: Clarify what zlib-sync does

* docs: Update docs site welcome

* src/docs: Remove `ws.compress` from docs

This is a deprecated parameter and you shouldn't use it unless you have zlib-sync installed, and even then, compression is automatically enabled

* docs: Apply suggestion

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-02-13 22:48:36 +01:00
Sugden
6770c7c786 typings: add invite events to WSEventType and constants (#3782)
* fix event typings

* add ws events to jsdoc
2020-02-13 22:46:46 +01:00
Ryan Munro
a36f3869b3 fix(Message): handle undefined/null content in cleanContent getter (#3778)
* Handle undefined/null content in Message#cleanContent

* Typings

* Update typings/index.d.ts

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-12 23:07:34 +01:00
Sugden
878cc050d4 fix(Guild): use snake case when editing system_channel_flags (#3781) 2020-02-12 22:47:24 +01:00
Sugden
562b5bfca7 refactor(VoiceChannel): use Permissions.FLAGS in speakable (#3780) 2020-02-12 22:42:43 +01:00
Sugden
d43692b0f2 docs(Guild): channels is a manager of channels (#3779) 2020-02-12 22:29:16 +01:00
Ryan Munro
62b227c2bd fix(BaseManager): BaseManager#valueOf should return cache (#3776)
* BaseManager#valueOf should return cache

* Update Util#flatten to handle valueOf being a Collection

* Update Util.js - typo

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
2020-02-12 22:26:17 +01:00
Ryan Munro
592021df92 feat(Message): throw a TypeError if delete is passed a non-object (#3772) 2020-02-12 22:25:14 +01:00
SpaceEEC
46e8bc44fc feat(BitField): add BitField base class (#3759)
* feat(BitField): add BitField base class

* fix(Permissions): properly deprecate the getters/setters
2020-02-12 22:23:48 +01:00
BorgerKing
b7ccf9a53e docs: info tag for ActivityType regarding CUSTOM_STATUS (#3758) 2020-02-12 22:23:35 +01:00
BorgerKing
3f8ea38b3a docs: info tag for ActivityType regarding CUSTOM_STATUS (#3757) 2020-02-12 22:23:06 +01:00
Ryan Munro
dbdb49ee1c feat(GuildAuditLogs): handle new event types (#3760)
* Define new AuditLogActions

* Backport constructor rewrite

* Typings

* fix(GuildAuditLogEntry): switch on correct property, coerce to numbers, simplify extra for deleted entities

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-12 18:42:57 +01:00
Sugden
149f72b50b typings(GuildMemberManager): fetch with no parameters returns collection (#3773) 2020-02-12 18:40:20 +01:00
Androz
94bb268639 docs: add extends to ChannelManager, cache is not nullable, resolveID accepts an object (#3771)
* Add extends to docs

* Cache shouldn't be nullable

* jsdoc: use same type for both resolve methods
2020-02-12 18:36:08 +01:00
SpaceEEC
92bc634520 docs(*Manager): fix child classes' cache type annotations (#3777) 2020-02-12 18:28:25 +01:00
Sugden
324d9e0a3a fix(TextChannel): remove old nsfw regex check (#3775) 2020-02-12 18:24:35 +01:00
BorgerKing
bbdbc4cfa7 feat: remove datastores and implement Managers (#3696)
* Initial commit: add 5 initial managers

- Base manager
- GuildChannelManager
- MessageManager
- PresenceManager
- Reaction Manager
- Added LimitedCollection

* Add GuildEmojiManager, various fixes

* Modify some managers and add guildmembermanager

* Initial integration

* Delete old stores

* Integration part two, removed LRUCollection

- Most of the integration has been finished
- TODO typings
- Removed LRUCollection, needless sweeping

* Typings + stuff i somehow missed in ChannelManager

* LimitedCollection typings/ final changes

* Various jsdoc and syntactical fixes, Removed Util.mixin()

* tslint fix

* Grammatical and logical changes

* Delete temporary file placed by mistake

* Grammatical changes

* Add missing type

* Update jsdoc examples

* fix: ChannelManager#remove should call cache#delete not cache#remove

* fix recursive require

* Fix missed cache in util

* fix: more missed cache

* Remove accidental _fetchMany change from #3645

* fix: use .cache.delete() over .remove()

* fix: missing cache in ReactionCollector

* fix: missed cache in client

* fix: members is a collection not a manager

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* fix: various docs and cache fixes

* fix: missed cache

* fix: missing _roles

* Final testing and debugging

* LimitedCollection: return the Collection instead of undefined on .set

* Add cache to BaseManager in typings

* Commit fixes i forgot to stage yesterday

* Update invite events

* Account for new commit

* fix: MessageReactionRemoveAll should call .cache.clear()

* fix: add .cache at various places, correct return type

* docs: remove mentions of 'store'

* Add extra documented properties to typings

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-02-11 20:21:07 +01:00
SpaceEEC
83bc6e0779 fix(Guild): update premiumSinceTimestamp on guild member update 2020-02-07 19:13:02 +01:00
didinele
fe7df708e4 typings: add HTTPOptions#api and export Constants as a value (#3768)
* fix(typings): Export Constants correctly

* fix(typings): HTTPOptions#api was missing

* fix some odd indent

* add semi to make CI happy uwu
2020-02-07 18:46:03 +01:00
Souji
364914fd35 fix(GuildMember): manageable - let owner override (#3766)
This backports #3765
2020-02-07 18:27:56 +01:00
Souji
3f039016af fix(GuildMember): manageable - let owner override (#3765)
* if the bot is owner of the guild the target is managebale
* even though both roles are on the same position
2020-02-07 18:27:05 +01:00
Vlad Frangu
b4e56d3e0e src: fix up WebSocketShard errors (#3722)
* src: Fix up WebSocketShard errors

* typings: Forgot to update

* src: Forgot debug variable

* src: Fix issue Bella found
If the WS was not connected when the HELLO timeout passes
(CONNECTING, etc), the shard would get stuck
due to never rejecting the WebSocketShard#connect
Promise with the DESTROYED event
2020-02-02 11:12:58 +01:00
SpaceEEC
c955fd00c7 feat(Integration): add guild integrations (#3756) 2020-02-02 11:11:31 +01:00
SpaceEEC
a12e1e87ee typings(Constants): add CUSTOM_STATUS to ActivityTypes 2020-02-01 21:14:02 +01:00
SpaceEEC
2589db6633 feat(Constants): add CUSTOM_STATUS to ActivityTypes 2020-02-01 21:12:58 +01:00
SpaceEEC
17b8b23b80 feat(Presence/Game): multiple activities and custom status (#3747)
* feat(Presence): add activities

* feat(Game): add created* and emoji
2020-02-01 18:27:20 +01:00
SpaceEEC
ccd60438df feat(Collector): add idle option (#3746) 2020-02-01 18:23:56 +01:00
SpaceEEC
fbcd363ec9 fix(Voice*): fix speaking event and voice receive (#3749)
* fix(Voice*): synthesize speaking event from UDP packets

* fix(VoiceReceiver): skip over undocumented Discord byte

See #3555

* fix(VoiceConnection): play frame silence before emitting ready

* typings: account for changes in private api
2020-01-31 22:37:11 +01:00
SpaceEEC
6d7e1e4953 fix: remove for..in in favor of Object.keys (#3745) 2020-01-31 11:38:47 +00:00
PLASMAchicken
6a381c68a2 chore(README): update link to Discord.js guide v12 changes (#3751)
* Update link to discord.js guide v12 changes

* Suggested Changes

* Suggested Changes

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
2020-01-31 11:38:10 +00:00
Jyguy
8e9e93da1d docs(Guild): fetchBan returns a promise (#3752) 2020-01-29 18:54:10 +01:00
BorgerKing
030d263a9e feat(MessageReaction): add remove method and Client#messageReactionRemoveEmoji (#3723)
* Add support for MessageReaction#remove and MESSAGE_REACTION_REMOVE_EMOJI

* Remove reaction from cache

Co-Authored-By: matthewfripp <50251454+matthewfripp@users.noreply.github.com>

* fix: message may be partial

* Clarify what the event entails

* Document client in MessageReaction

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* await the REST call

* Add MessageReaction#remove to typings

Co-authored-by: matthewfripp <50251454+matthewfripp@users.noreply.github.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-01-25 20:00:53 +01:00
Ryan Munro
ab7f9e80b4 feat(MessageReaction): backport removeAll and MessageReactionRemoveEmoji event (#3741)
* Add new action and websocket handler

* Add REST method for removing reaction emoji

* Update Message#_removeReaction to handle removing whole emoji

* Add MessageReaction#removeAll and update typings

* Apply uncached user fix
2020-01-25 15:36:35 +01:00
Ryan Munro
d8b4725caa fix(TextChannel#bulkDelete): use GenericAction#getMessage to handle return value correctly (#3664)
* Corrected the handling of the action

* Apply same fix to handling of single message in bulkDelete

* Revert to using await
2020-01-25 15:27:39 +01:00
PLASMAchicken
6b297b8776 chore: bump version to 11.6.0-dev (#3731)
* Update package.json

* Change Version String after amishshah's  suggestion

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
2020-01-25 15:09:30 +01:00
Sugden
3ea9ac57dd fix(ClientUser): verified and enabled properties resetting (#3733)
* fix(ClientUser) verified and enabled properties resetting

* set this.mfaEnabled to null if it is undefined

* add missing curly brackets

* fix typo
2020-01-25 15:08:25 +01:00
BorgerKing
90aa5b3500 feat(GuildMemberStore): make timeout refresh after every GUILD_MEMBERS_CHUNK (#3645) 2020-01-24 17:08:40 +01:00
Gryffon Bellish
b81f771007 cleanup: fix deepscan issues (#3740)
* fix: don't double check if shards are auto.

* fix: remove useless roles array.

* fix: remove useless undefined checks.

* fix: remove useless `this` binding

* Apply suggestions from code review

Co-Authored-By: Sugden <28943913+NotSugden@users.noreply.github.com>

* Fix: Space's suggestion

* Fix: time is always truthy

* Check if it's an invalid date.

Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
2020-01-24 16:58:23 +01:00
SpaceEEC
099a1a47e8 fix(*Collector): always run postCheck, remove 'translatation' of message collector options (#3718)
* fix(*Collector): always run postCheck, correctly 'translate' message collector options

* fix(MessageCollector): remove translation, fix postCheck conditions
2020-01-24 16:56:04 +01:00
SpaceEEC
30adb378fc feat(Webhook): backport missing properties (#3710)
* feat(Webhook): add avatarURL getter

This backports: https://github.com/discordjs/discord.js/pull/3625

* feat(Webhook): add type, createAt, and createdTimestamp

This backports: https://github.com/discordjs/discord.js/pull/3585

* feat(Webhook): add url getter

This backports: https://github.com/discordjs/discord.js/pull/3178

* docs(Webhook): add missing type and readonly tags
2020-01-24 16:52:52 +01:00
SpaceEEC
88b675d38a feat(MessageReaction): backport animated, client, created*, and url (#3711) 2020-01-24 16:50:16 +01:00
SpaceEEC
4ca18647ba feat(MessageAttachment): add spoiler getter (#3713) 2020-01-24 16:45:52 +01:00
SpaceEEC
a505a55e03 fix(RichPresenceAssets): add Twitch preview link for largeImageURL (#3715) 2020-01-24 16:43:16 +01:00
SpaceEEC
903f6ca75f fix: only setMaxListeners when max listeners is not 0 (#3716) 2020-01-24 16:41:37 +01:00
BorgerKing
929ff9ccd0 feat(Client): add support for INVITE_CREATE and INVITE_DELETE events (#3720)
* Add support for new Invite events

* Merge typings for events

Co-Authored-By: Sugden <leoaustin675@gmail.com>

* Add warning about requiring permissions

* Null check channel and guild

* fix: .guilds not .channels
2020-01-24 16:38:26 +01:00
Ryan Munro
40afbc1d7e feat(Client): backport INVITE_CREATE and INVITE_DELETE events (#3728)
* Backport INVITE_CREATE and INVITE_DELETE

* Register events to Websocket

* Dont create an Invite if the guild is null

* Null check channel too
2020-01-24 16:34:59 +01:00
Ryan Munro
17237c70c8 typings(TextChannel): topic can be null (#3687)
* Mark topic as nullable for TextChannel

* Backport separate NewsChannel typings

* Ensure NewsChannel#rateLimitPerUser is undefined

* Revert rateLimitPerUser, considered breaking

* Add rateLimitPerUser back to typings

* Linting

* Revert NewsChannel extends TextBasedChannel
2020-01-24 16:33:19 +01:00
Sugden
c779fe3670 feat(Guild): add fetchBan method (#3726)
* Add error for not resolving ID to fetch ban

* Add Guild#fetchBan

* add missing !

* typings

* lint fixes

* add jsdoc description
2020-01-24 15:29:53 +01:00
Carter
63293fe14d chore(License): bump license year (#3734) 2020-01-22 08:21:43 +00:00
SpaceEEC
464ef25898 fix(ClientDataResolver): return a user in resolveUser when passing guild (#3719) 2020-01-20 22:02:28 +01:00
Sugden
877577badc typings(RichPresenceAssets): *ImageURL's options are optional (#3727) 2020-01-20 22:02:02 +01:00
Souji
d8419ac2c7 docs(MessageMentions): backport mention order notice (#3712) 2020-01-19 13:09:33 +01:00
SpaceEEC
c5d2b96524 fix(VoiceConnection): use Client#clearTimeout to clear timeouts (#3709) 2020-01-19 13:08:49 +01:00
SpaceEEC
01826aeefe feat(Guild): add setBanner method and banner to edit (#3708) 2020-01-19 13:07:09 +01:00
SpaceEEC
6302afb84b docs(MessageMentions): channels are actually in order (#3705)
* docs(MessageMentions): channels are actually in order

* docs(MessageMentions): readd info about order for channels

* docs(MessageMentions): reword info to account for rtl locales
2020-01-19 13:06:21 +01:00
SpaceEEC
f501d06c0d fix(Presence): account for multiple activities everywhere (#3703)
* fix(Presence): account for multiple activities everywhere

* refactor(Presence): make initialization of 'activities' more readable
2020-01-19 13:05:45 +01:00
Ryan Munro
0f49d67e2e feat(Message/Mentions): implement caching of members (#3684)
* Convert message#member to a getter

*  Try to cache members from data in message payloads

* Cache mentioned members

* Revert Message#member getter - breaking change

* Revise member caching

* Revise member mention caching

* Pass member to _addMember correctly

* Use message.guild instead of this.guild

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* Merge if's onto one line

* fix(Message): use this.author.id to check cache

Discord does not send an id in the member data here

* chore(Message): reindent equals

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-01-19 12:27:57 +01:00
BorgerKing
cbb8db3058 feat(Collectors): make collectors auto-stop when relevant structures are deleted (#3632)
* Collectors: make Collectors automatically stop when Channel, Guild, or Message are deleted.

* fix potential error with DM collectors

* Message collectors dont have a `this.message` you dummy

* Fix(various): nitpicks, documentation, typings, and stray error

* Pleasing mr tslint

* fix: typings

* Grammatical fixes

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* Fixing the linting after space's suggestions

* docs(ReactionCollector): remove whitespace

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2020-01-19 11:24:55 +01:00
Amish Shah
6ab46491c8 Add internal support for @discordjs/opus to v11 (#3700)
* Add internal support for @discordjs/opus

* Remove redundant try/catch

* fix: use setBitrate method in @discordjs/opus

* chore: tidy up opus imports

* fix: correct imports for DiscordJsOpusEngine

* chore: update docs to prefer @discordjs/opus

* chore: bump prism-media to 0.0.4 to allow ffmpeg-static
2020-01-17 20:58:49 +00:00
Gryffon Bellish
69c79a4136 typings/docs(GuildEmoji): id isn't nullable (#3694)
* Fix: GuildEmoji#id isn't nullable

* Move ID to be alphabetical

* Add JSDoc to say it's not nullable

* fix linting
2020-01-17 20:11:14 +01:00
Crawl
6a0fe467e5 docs: replace all occurances of node-opus with @discordjs/opus (#3698)
* docs: replace all occurances of node-opus with @discordjs/opus

* chore: leave in node-opus in case not everyone switched
2020-01-16 14:10:48 +01:00
Crawl
d096e40f6f feat/fix: use updated eslint action (#3699) 2020-01-16 12:59:03 +01:00
Helmasaur
d77229f423 chore: ffmpeg package in the voice doc (#3697)
ffmpeg package changed from "ffmpeg-binaries" to "ffmpeg-static"
2020-01-16 12:57:20 +01:00
Souji
7f99be739a docs(MessageMentions): add sort order notice (#3693)
* mention order returned from API
* not left to right in text
2020-01-14 11:28:19 +01:00
Gryffon Bellish
75fe1faf2f Remove BroadcastAudioPlayer from typings (#3692) 2020-01-13 22:45:58 +00:00
Amish Shah
629c57f890 fix: regression (changing voice servers) 2020-01-13 22:29:05 +00:00
SpaceEEC
36c0496ea5 fix(Guild): assign GuildMember#selfStream, if present, when adding a member 2020-01-13 21:43:42 +01:00
SpaceEEC
ee0b7c155a feat(Presence): add support for multiple activities (#3661)
* feat(Presence): add support for multiple activites

* typings(Presence): fix spelling of 'activities'

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
2020-01-13 20:28:29 +00:00
Ryan Munro
07996d12a2 feat(Constants): backport VerificationLevels and missing APIError codes (#3688)
* Add VerificationLevel constants

* Update APIError constants
2020-01-13 20:47:55 +01:00
Vlad Frangu
c23cc7a42e src: Cleanup event listeners on WebSocket connections (#3681)
* src: Cleanup event listeners on WebSocket connections
Should prevent #3641 from happening, as well as double connections on a shard

* typings: Forgot to add the method
2020-01-13 18:53:07 +00:00
Vlad Frangu
684bb1bf36 src: Remove _trace from different places in the WS (#3679)
* src: Remove `ws._trace` from READY

* src: Remove `ws._trace` from RESUME

* lint: Fix lint by removing unused packet (#7)

Co-authored-by: bdistin <bdistin@gmail.com>
2020-01-13 17:54:15 +00:00
Ayyan Lewis
45cd58b68c types(VoiceBroadcast): add subscribers property (#3677)
* types(VoiceBroadcast): add subscribers property

* types(VoiceBroadcast): change player property to private

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

Co-authored-by: Amish Shah <amishshah.2k@gmail.com>
2020-01-13 17:01:16 +00:00
Antonio Román
53a1f8fcd4 refactor: Remove util alias export (#3691) 2020-01-13 16:16:22 +00:00
Antonio Román
62afafdbe9 typings: Fixed build error (#3689) 2020-01-13 16:48:49 +01:00
Tenpi
8014ddcd1c feat: dynamic property for ImageURLOptions (#3530)
* Added dynamic property to ImageURLOptions

* fixes

* order

* typings fix

* made dynamic false by default

* add curly spaces
2020-01-13 14:32:29 +00:00
SpaceEEC
400cb56358 fix(ShardingManager): assert shardList to be spawned, not totalShards (#3649) 2020-01-13 14:12:18 +00:00
SpaceEEC
11f9118551 fix(BitField): remove for..in in favor of Object.entries (#3650)
* fix(BitField): remove for..in in favor of Object.keys

* refactor: do not re-resolve bits

Co-Authored-By: bdistin <bdistin@gmail.com>

Co-authored-by: bdistin <bdistin@gmail.com>
2020-01-13 14:07:54 +00:00
Souji
59205a2152 fix: provide count on bulk deletion (#3682)
* GuildAuditLogsEntry should provide count as extra in case of  MESSAGE_BULK_DELETE
* inner class: GuildAuditLogsEntry in GuildAuditLogs.js
2020-01-13 14:02:31 +00:00
Ryan Munro
f6d1db6a24 Backport documentation fixes (#3683)
* Presence does not extend Base, therefore presence.client was undocumented

* Document Client#fetchVoiceRegions returning a promise
2020-01-13 14:00:13 +00:00
SpaceEEC
b5825c33b0 feat(Speaking): add PRIORITY_SPEAKING bit (#3680) 2020-01-13 13:58:40 +00:00
Vlad Frangu
5556b05241 src: add deprecation warning related to removel of uws (#3648)
* src: Add deprecation warning related to uws

* lint: Fix lint

* src: Simplify code
2020-01-12 15:16:27 +01:00
didinele
f74ae12d6a fix(typings): remove VoiceChannel#connection (#3676) 2020-01-11 20:42:01 +01:00
Saya
a53d86579b typings(BaseClient): remove delay parameter from setImmediate (#3667)
There is no delay parameter on setImmediate in Node.JS docs:
https://nodejs.org/docs/latest-v12.x/api/timers.html#timers_setimmediate_callback_args
2020-01-09 23:14:55 +01:00
SpaceEEC
fbe9bc499b feat(Webhook): add ability to change channel and specify reason to edit (#3587)
* feat(Webhook): add ability to change channel and specify reason to edit

* fix(RESTMethods): update channelID of the webhook too
2020-01-05 18:34:00 +01:00
SpaceEEC
d1d0d75d4a fix(ChannelDelete): mark messages of a deleted channel as deleted (#3572) 2020-01-05 18:29:14 +01:00
SpaceEEC
367c80070f feat(Permissions): add any method (#3571)
* feat(Permissions): add any method

* typings: add Permissions#any

* fix(Permissions): resolve doesn't take a checkAdmin parameter

Co-Authored-By: bdistin <bdistin@gmail.com>

* docs(Permissions): remove trailing space, add returns annotation

Co-authored-by: bdistin <bdistin@gmail.com>
2020-01-05 18:24:08 +01:00
SpaceEEC
cbabc1663c fix(Voice*): internally disconnect and cleanup when forcibly disconnected (#3597) 2020-01-05 18:10:20 +01:00
Gryffon Bellish
d2ef02906c cleanup(DataResolver): stats can't be falsy (#3651) 2020-01-05 17:45:16 +01:00
izexi
6af0da1043 feat(Partials): add DMChannel/MessageReaction#fetch() and PartialTypes.REACTION (#3474)
* add DMChannel#fetch() & Action#getChannel({recipients})

* ref for MessageReaction partial

* typings

* add PartialTypes.REACTION

* accommodate for fully removed reactions

* fix incorrect wording and typo

* typings: MessageReaction#count is nullable

* typings: mark MessageReaction#partial as readonly

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* fix(User): fetch dm channel if cached one is partial

* docs: add missing comma

Co-Authored-By: Antonio Román <kyradiscord@gmail.com>

* fix: accomodate for new reactions

* fix: updating existing/new count on _patch

* docs: typo

* for consistency

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
2020-01-05 16:45:49 +01:00
tipakA
bf31b28ad9 feat(RichPresenceAssets): add Twitch preview link for largeImageURL (#3655) 2020-01-05 00:50:38 +01:00
Jyguy
155b682f6c typings(GuildEmoji): make url not-nullable (#3656)
* typings(GuildEmoji): make url not-nullable

* make GuildEmoji.url readonly
2020-01-04 23:23:01 +01:00
Cadence Fish
c734979ad4 typings(ShardingManager): add options.shardList (#3657) 2020-01-03 13:53:27 +01:00
SpaceEEC
97eac663b3 feat(MessageMentions): cache mentioned members (#3601) 2019-12-27 19:28:04 +01:00
SpaceEEC
e660ea90cc fix(Webhook): edit channel when editing avatar (#3588) 2019-12-27 19:27:48 +01:00
SpaceEEC
ea76a56639 feat(Webhook): add type property and created* getters (#3585)
* feat(Webhook): add created* getters

* feat(Webhook): add type property

* typings(WebhookFields): use primitive string for url getter

Co-Authored-By: Gryffon Bellish <owenbellish@gmail.com>

* fix(Webhook): token can be null

Co-authored-by: Gryffon Bellish <owenbellish@gmail.com>
2019-12-27 19:27:34 +01:00
SpaceEEC
fc27ce1a15 typings(Bitfield): add hasParams to toArray, fix serialize's type (#3579)
* typings(Bitfield): add hasParams to toArray, fix serialize's type

* fix: apply suggested changes

* chore: remove incorrect whitespace

* fix: make params optional

* nit: pluralize bit in Permissions#missing

* nit: group non-static methods together
2019-12-27 19:26:41 +01:00
NightScript
50ed3293a5 chore: issue config refactor (#3640)
* Create config.yml

Instead of making an entire new page with just text talking about the discord server (which they could ignore, as most people don't read), just link people directly to the discord server

* Delete question---general-support-request.md
2019-12-25 03:29:19 +01:00
Gryffon Bellish
d4333f5bbe chore: node version in package.json (#3643) 2019-12-25 03:28:09 +01:00
Gryffon Bellish
45b8971000 deps: mark utf-8-validate as optional, remove mentions of uws and zucc (#3638)
* Mark utf-8-validate as optional

* remove uws and zucc
2019-12-23 23:01:07 +01:00
Vlad Frangu
710101c580 src(WebSocket): fix race condition (#3636)
A race condition caused Client#user to be null in the ready event if the client handled 0 guilds.
2019-12-22 10:31:26 +01:00
Antonio Román
b4f00bfb6b feat: widen GuildResolvable to include more structures (#3512)
* feat: Widen GuildResolvable to include GuildChannel and GuildMember

* docs: Documented the new overloads

Co-Authored-By: Gryffon Bellish <owenbellish@gmail.com>

Co-authored-by: Gryffon Bellish <owenbellish@gmail.com>
2019-12-21 21:28:09 +01:00
ottomated
f578cce9ac feat(Guild): add systemChannelFlags (#3559)
* Add systemChannelFlags bitfield to Guild

* Implement @vladfrangu's suggestions

* fix: apply suggestions, reverse order of flags, reword docs

* docs: add SystemCHannelFlagsResolvable typedef

Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2019-12-21 21:27:14 +01:00
Charlie
e13b3f550d typings: TextChannel.topic & NewsChannel.topic should be nullable (#3628)
* Fix GuildChannel#topic to be optional

* Update typings/index.d.ts

Implement the suggested change from optional to null return

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* Update typings/index.d.ts

Implement the suggested change from optional to null return

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

Co-authored-by: izexi <43889168+izexi@users.noreply.github.com>
2019-12-21 21:12:35 +01:00
Sugden
99e8d3c540 cleanup: remove acknowledge method from TextChannel & DMChannel (#3635)
* Update TextChannel.js

* remove acknowledge method
2019-12-21 20:32:24 +01:00
SpaceEEC
7d74e7e419 typings(Extendable): add missing channels (#3581) 2019-12-20 11:58:46 +01:00
Vlad Frangu
5519d6fbaa src: sharding cleanup and checkReady rewrite (#3393)
* src: Step 1 of who knows how many

* src: Remove accidentally committed test file

* src: Remove useless added property in package.json

* docs: Trailing spaces, come back >.>

* src: Buhbye uws, we will miss you..not!

* src: Move 'auto' shard selection from totalShardCount to shards

* src: tweak

* src: Filter out floats from shard IDs
You want half of a shard or what?

* src: Misc cleanup and bugfix for GUILD_BAN_ADD

* src: Rewrite checkReady

* src: Misse this while merging master into my branch

* typings: Bring these up to date

* typings: Forgot allReady event

* src: Don't checkReady if the shard isn't waiting for guilds

* src: Fix a possible bug for when the ws dies and the session becomes -1

* src: Hopefully fix last edge case that could case a shard to infinitely boot loop

* src: Rename totalShardCount to shardCount

* src: Small bugfix

* src: Correct error message for shardCount being imvalid

Co-Authored-By: bdistin <bdistin@gmail.com>

* src: Small tweaks

* src: If this doesn't fix the issues I'm gonna throw a brick at my PC

* src: I swear, STOP BREAKING

* src: *groans at a certain snake*

* src: Use undefined instead of null on destroy in close event

Setting it to null sets the close code to null, which causes a WebSocket error to be thrown. The error is thrown from WebSocket, although there is no connection alive. Fun times!

* src: @SpaceEEC's requested changes

* src: Remove zucc from discord.js

Discord is removing support for it, sooo... Bye bye

* src: Missed this

* src: Apply @kyranet's suggestions

Co-Authored-By: Antonio Román <kyradiscord@gmail.com>

* src: @kyranet's suggestions

* src: Remove pako, update debug messages
- Pako is officially gone from both enviroments
  Install zlib-sync on node.js if you want it
- Improve a few debug messages some more
- Discover that internal sharding works in browsers but please don't do that
2019-12-15 20:45:27 +01:00
Gryffon Bellish
f56b442e83 typings(Bitfield): use IterableIterator instead of Iterator (#3599) 2019-12-15 20:26:09 +01:00
izexi
43782839ec feat: add new MessageFlags.FLAGS & User#system (#3603)
* feat: add new FLAGS

* feat: add system property

* typings: add User#system & new MessageFlagsStrings
2019-12-15 20:23:06 +01:00
Carter
330d5db586 feat(Webhook): addition of Webhook#avatarURL function (#3625)
* feat: addition of Webhook#avatarURL

* typings: added Webhook#avatarURL

* fix: trailing space

* docs: fixed jsdoc function description

* fix: typo
2019-12-15 20:20:15 +01:00
BorgerKing
123713305a docs(ReactionStore): resolveID takes a reaction, not role (#3617)
* Docs: ReactionStore.resolveID should take Reaction, not role

* Make param lowercase

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>
2019-12-08 19:52:03 +01:00
sillyfrog
4585d965b4 Start/Stop speaking events on UDP packets (#3578)
* Start/Stop speaking using incomming UDP packets

* Fix ESLint errors

* Updates for styling consistency

Co-Authored-By: Gryffon Bellish <owenbellish@gmail.com>

* Minor improvements

* Acutally use previousTimeout

* Use BaseClient setTimeout and refresh()

* Update README to match node version for refresh()

* Update comment to match startSpeaking

* Correctly report Priority bit

* Fix ESlint errors
2019-12-06 11:59:57 +00:00
Clemens E
bb8333a4f9 Handle voice errors outside of authenticated event (#3520) 2019-12-06 11:56:29 +00:00
Jeroen Claassens
2ca74d6b63 feat(Activity): support for CUSTOM_STATUS activity type (#3353)
* feat: support for custom status in activity

* nit(typings): order properties
2019-12-05 13:13:42 +01:00
BannerBomb
1b1289b35e misc(index): export Store- and NewsChannel (#3594)
* Added Store and NewsChannel to exports

Added the StoreChannel and NewsChannel structures to the module exports.

* keeping the list in alphabetical order

I moved the StoreChannel and NewsChannel exports that I added in the last commit in their right position to keep things alphabetized.
2019-11-25 16:17:30 +01:00
Gryffon Bellish
100360705a fix(APIRouter): use proper symbol for util.inspect (#3589) 2019-11-20 18:11:23 +01:00
Jyguy
cbde819b6a typings(GuildAuditLogsFetchOptions): specify concrete type of 'type' property (#3586) 2019-11-20 00:21:47 +01:00
Gryffon Bellish
d39f17925d fix(Invite): fix valueOf returning undefined (#3582)
* Update Invite.js

* Fix typings

* Fix ESLint errors
2019-11-19 21:54:35 +01:00
Carter
1bcc0c2e1d feat(GuildAuditLogs): add new event types (#3584)
* adds more audit-log entries

this adds additional audit-log types from https://discordapp/discord-api-docs/pull/1191

* typings for new audit-log entries

* typings for new audit-log entries

* fix action numbers
2019-11-19 21:51:26 +01:00
λtlas
1d6606293a docs(Client): clarify whose ToS are being violated (#3580) 2019-11-19 21:50:45 +01:00
Edward Wang
1352bff2fd docs(README): link to guide page instead of source (#3566)
* Fixed the Update Guide Link

Original link pointed to https://github.com/discordjs/guide/blob/v12-changes/guide/additional-info/changes-in-v12.md, which is invalid. I'm not sure if the link I put (https://github.com/discordjs/guide/blob/master/guide/additional-info/changes-in-v12.md) is the correct one, but I will assume it is.

* Used link to the DJS guide.
2019-11-09 20:52:55 +01:00
Carter
9a31e6e53a docs(README): travis badge => github actions badge (#3569)
* travis badge => github actions badge

* this is why you don't copy paste :^)
2019-11-09 20:52:06 +01:00
matthewfripp
38d370fb18 feat(MessageAttachment): add spoiler property (#3561)
* feat(MessageAttachment): add spoiler property

* typings

* Implement suggestions

* Make readonly

Co-Authored-By: Antonio Román <kyradiscord@gmail.com>
2019-11-04 14:44:36 +01:00
Jiralite
cc466fa4b9 docs: NewsChannel and StoreChannel (#3557)
* Added news & store

* Update GuildChannel.js

* Added in News and Store
2019-11-04 11:35:14 +01:00
Purpzie
99466a99ed typings(Util): use StringResolvable (fixes old pull) (#3556)
Fixes my extremely old pull #3212 that didn't actually update the typing (Didn't know at the time.)
2019-11-04 11:33:42 +01:00
Albus Dumbledore
e26697f07d docs(readme): table of contents (#3539) 2019-11-04 11:29:19 +01:00
SpaceEEC
2e20e8092b fix(*Collector): account for a max listener count of 0 (#3504) 2019-11-04 11:25:43 +01:00
Jeroen Claassens
3c634b2a26 chore: mark optional peerDependencies as optional (#3511) 2019-11-04 11:25:14 +01:00
Marwin M
3a9eb5b929 Fix Opus voice streams (#3555)
This fixes a wrong assumption about incoming discord voice packets revealed during a recent discord change that broke incoming opus voice streams
2019-10-29 12:22:21 +00:00
Gryffon Bellish
9bcb6a04ba fix(VoiceConnection): clear timeouts using Client#clearTimeout (#3553)
* Update VoiceConnection.js

* fix last instance
2019-10-27 16:58:38 +01:00
SpaceEEC
96037e107f feat(GuildMember): add selfStream (#3522) 2019-10-27 10:27:43 +01:00
SpaceEEC
f91ad7023b feat(GuildMember): filter out duplicate roles when updating (#3502) 2019-10-27 10:27:01 +01:00
SpaceEEC
18613526bd docs(VoiceStatus): document name -> value, link in VoiceConnection#status (#3500) 2019-10-27 10:26:08 +01:00
SpaceEEC
91600a6946 fix(VoiceReceiver): delete opus encoder from map in stoppedSpeaking (#3499) 2019-10-27 10:24:35 +01:00
Souji
7011c512fb fix: document ChannelData#reason (#3549)
* fix: document ChannelData#reason

* update respective typings
* closes #3548

* update: add note creation only

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>
2019-10-22 21:17:56 +02:00
Alexander Kashev
16db92ede8 typings(GuildEmoji): restore deletable, remove inherited property deleted (#3543)
* Typings: restore deletable on GuildEmoji

* Remove inherited property "deleted"
2019-10-18 13:06:34 +02:00
rei2hu
9e0705cbc3 fix(Message): check for edited_timestamp in data when patching message (#3535)
* check for data.edited_timestamp

* actually i should do it like this for consistency

* indentation
2019-10-18 11:55:35 +02:00
Antonio Román
a61cfc3004 docs: VoiceStateUpdate always sends an instance of VoiceState (#3537)
* docs: VoiceStateUpdate always sends the old

* typings: Update definition for voiceStateUpdate event
2019-10-18 11:32:19 +02:00
Alexander Kashev
ca1bd61f4f typings(Emoji): remove deletable, add deleted, mark nullable props (#3542) 2019-10-18 11:30:49 +02:00
bdistin
c3228b4263 fix(docslink): partialtypes (#3510) 2019-10-12 00:54:02 +02:00
Tenpi
79133b4d5e at(typings): partial Types (#3493)
* test

* test 2

* update

* update

* replaced double quotes

* Made message.guild and message.member nullable

* replaced double quotes again (oops)

* missing semicolons

* removed fetch from Omit

* Added Partialize generic type

* Created interfaces (prettier intellisense)

* joinedAt/joinedTimestamp are nullable and fixed conflict
2019-10-12 00:52:00 +02:00
Antonio Román
a60f8b3d49 src(constants): add missing APIErrors (#3531)
* src: Updated APIErrors

* typings: Updated constants
2019-10-11 11:01:16 +02:00
izexi
a8f06f251f feat(VoiceState): add VoiceState#streaming (#3521)
* feat: add VoiceState#streaming

* typings: add VoiceState#streaming
2019-10-04 16:44:35 +02:00
Souji
48856c0815 fix: set messages deleted when their channel is deleted (#3519) 2019-10-04 16:44:04 +02:00
Souji
2610bf57ae feat(GuildChannel): backport permissionsLocked getter (#3507)
* backport(GuildChannel): GuildChannel#permissionsLocked

* typings: GuildChannel#permissionsLocked

* fix(typings): mark permissionsLocked getter as readonly
2019-10-04 16:43:12 +02:00
rei2hu
8ddd0616a9 fix(Util): make arraysEqual avoid mutating the input arrays (#3506) 2019-10-04 16:39:56 +02:00
SpaceEEC
a8e365743c typings: optional reason for setNSFW and add deleted properties (#3505)
* typings: optional reason for setNSFW and add deleted properties

* typings(Guild): setDefaultMessageNotifications' reason is also optional
2019-10-04 11:20:56 +02:00
izexi
94ce19dd1a typings: mark GuildMember#nickname as nullable (#3517) 2019-10-04 11:19:55 +02:00
izexi
3458693748 typings: mark GuildMember#nickname as nullable (#3516) 2019-10-04 11:19:46 +02:00
Souji
2a78b00454 fix(typings): GuildChannel#parent and #parentID are nullable (#3509) 2019-10-02 14:26:53 +02:00
Souji
e936f071c0 fix(typings): GuildChannel#parentID is nullable (#3508) 2019-10-02 14:26:42 +02:00
Vlad Frangu
a4f06bdffd src: support new message fields (#3388)
* src: Update channel pattern

* src: Remove useless non-capture group

* src: it's as though we're starting fresh

* src: Bring this up to date for reals now

* src: typings and a bug fix

* src: Add crossposted channels to message mentions

* src: Requested changes and add typings

* src: Move Object.keys outside loop

* typings: Fix enum being exported when it shouldn't

* src: Consistency with roles and users

* docs: Correct docstring for MessageFlags#flags

* docs: Correct docstring for MessageMentions#crosspostedChannels

* docs: Suggestions
Co-authored-by: SpaceEEC

* src: Reset flags to 0 if no flags are received on MESSAGE_UPDATE
2019-10-01 11:01:55 +02:00
Ryan Munro
505df2ebb3 backport(Guild): createChannel's default type incorrectly set (#3497)
Backports #3496 (a03e439d6b) to the 11.5-dev branch
2019-10-01 10:59:02 +02:00
Ryan Munro
a03e439d6b fix(GuildChannelStore): default channel type incorrectly set (#3496) 2019-10-01 10:56:14 +02:00
Jiralite
41c0dd44eb fix(BitField): throw when resolving invalid string constant
Checked to see if the permission actually exists.
2019-10-01 10:46:49 +02:00
Vlad Frangu
ea8b4e7355 docs/typings: Rename LURKABLE to PUBLIC and update GuildFeatures type (#3484)
* docs: Rename LURKABLE to PUBLIC

* typings: Update GuildFeatures type
2019-09-25 23:28:12 +02:00
Gryffon Bellish
d280d1b03f style: change let to const in MessageMentions (#3483) 2019-09-24 17:36:19 +02:00
Ryan Munro
60f89bd96f fix(stores): Add symbol.species for not-actual-stores (#3477)
* fix(stores): Add symbol.species for not-actual-stores

* Linting fixes
2019-09-22 23:50:41 +02:00
Vlad Frangu
748555036d typings: Add missing rateLimitPerUser property (#3480) 2019-09-22 17:07:44 +02:00
BadCoder1337
d05334fd3c typings: make TypeScript interaction with channels better (#3469)
* make channel returning methods generic

* channel's type inference from kind of channel

* add extends

* rename generic due to name convention

* edit overload

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts


Co-authored-by: Crawl <icrawltogo@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
2019-09-19 23:01:08 +02:00
1Computer1
d5831df7b1 fix: typings for this-polymorphism of collections (#3472)
* Fix typings for this-polymorphism of collections

* Update index.d.ts


Co-authored-by: Crawl <icrawltogo@gmail.com>
2019-09-18 00:53:00 +02:00
iCrawl
ea9e144190 fix(typings): remove leftover typeof 2019-09-11 02:11:31 +02:00
iCrawl
33ecdd4c50 fix(typings): collection constructor 2019-09-11 01:58:12 +02:00
Crawl
ac44a7fc57 fix(typings): collections import 2019-09-10 20:34:47 +02:00
Crawl
321beb73bd revert: "feat(Partials): add DMChannel/MessageReaction#fetch()… (#3468)
This reverts commit b0047c424b.
2019-09-10 19:49:56 +02:00
1Computer1
dad0cd8e81 feat: external collection package (#2934)
* Use external collection package

* Complete typings

* Document properly base collection class

* Add clone since sort is now in-place

* Update for latest changes to package

* Fix whitespace

* Update docs link

* Oops

* Update Collection.js

* Update index.d.ts
2019-09-10 17:44:47 +02:00
bdistin
278f185b64 fix(rate-limits): reactions buckets need to be shared with sub-… (#3439) 2019-09-10 17:29:44 +02:00
Charalampos Fanoulis
8dec251d3c github: add support file and redirect to it (#3302)
* github: add support file and redirect to it

* github: happily accept that suggestion
2019-09-10 17:14:07 +02:00
newt
37ecf7b826 feat(constants): add verificationLevels (#3369)
* add Util.parseVerification()

* Made the code much cleaner.

* Removed method and created constant.

* Lint!

* refactor(constants): capitalize VerficiationLevels and add a typedef

* Changed VerificationLevels typedef to singular.

Co-Authored-By: Will Nelson <will@wnelson.xyz>
2019-09-10 16:12:27 +02:00
izexi
b0047c424b feat(Partials): add DMChannel/MessageReaction#fetch() and Parti… (#3261)
* add DMChannel#fetch() & Action#getChannel({recipients})

* ref for MessageReaction partial

* typings

* add PartialTypes.REACTION

* accommodate for fully removed reactions

* fix incorrect wording and typo

* typings: MessageReaction#count is nullable

* typings: mark MessageReaction#partial as readonly

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* fix(User): fetch dm channel if cached one is partial

* docs: add missing comma

Co-Authored-By: Antonio Román <kyradiscord@gmail.com>
2019-09-10 16:09:06 +02:00
Carter
6f83e71555 feat: Guild#partnered (#3444)
* feat: Guild#partnered

* typings: added Guild#features

* fix: removed trailing space

* typings: made Guild#partnered readonly
2019-09-10 15:47:13 +02:00
SpaceEEC
8e0f525d91 fix(Role): throw TypeError in comparePositionTo (#3466) 2019-09-10 15:44:49 +02:00
SpaceEEC
4072ffb50d typings(GuildChannel): add members getter (#3467) 2019-09-10 15:44:00 +02:00
Will Nelson
c86a6154aa feat(VoiceState): add kick method (#3462)
* feat(VoiceState): add kick method

* feat(typings): add types for VoiceState#kick method
2019-09-10 10:00:04 +01:00
Ryan Munro
a6810e2eaa feat(Permissions): add new method Permissions#any (#3450)
* Add new method Permissions#any

* Update src/util/BitField.js

This is much better

Co-Authored-By: bdistin <bdistin@gmail.com>

* Remove unreachable code

* Gotta keep the linter happy

* Apply bdistin suggested change to both methods
2019-09-10 10:55:42 +02:00
iCrawl
4fc461c2f9 fix: browser-compatability
Fix #3453
2019-09-08 11:47:46 +02:00
iCrawl
6e616edc69 chore: keep_classnames literally everywhere 2019-09-08 11:46:47 +02:00
iCrawl
c71454f312 chore: add more voice files to ignore for webpack 2019-09-08 11:46:11 +02:00
Antonio Román
d252ddf9da docs: Document Message#author as nullable (#3464)
Fixes #3463
2019-09-08 09:49:10 +02:00
iCrawl
c5cbf8677e feat(typings): reply overloads for splitmessage 2019-09-06 12:03:21 +02:00
Schuyler Cebulskie
89a3a3a6da Lowercase webpack (their branding, not mine) 2019-09-04 01:04:31 -04:00
Schuyler Cebulskie
827cab805e Clean up workflows 2019-09-04 01:02:01 -04:00
BannerBomb
5d95a4b264 fix: Util#splitMessage when destructured (#3456) 2019-09-03 16:24:20 +02:00
iCrawl
0a2003095d ci: consistency in naming 2019-09-03 16:18:56 +02:00
iCrawl
0c14616ffc ci: reduce the amount of yml files 2019-09-03 16:08:25 +02:00
iCrawl
e7a961781c ci: add webpack workflow 2019-09-03 16:04:36 +02:00
iCrawl
fe71cecc2a ci: use the correct command 2019-09-02 13:27:34 +02:00
iCrawl
3ce60212e6 ci: run a lint cronjob every 12h 2019-09-01 15:41:07 +02:00
Schuyler Cebulskie
45af62a621 Update typings for renamed shard events 2019-08-31 17:18:18 -04:00
Schuyler Cebulskie
4b34f1acbe Remove past-tense naming on shard events 2019-08-31 17:14:48 -04:00
Yukine
9e6a73d1a0 typings(Client): remove 'resume', add 'replayed' parameter to 'shardResumed' (#3455)
corrected shardResumed & removed old resumed event
2019-08-31 22:17:46 +02:00
Crawl
89d9b0f498 fix(typings): partially revert #3448 2019-08-29 20:16:38 +02:00
Vlad Frangu
43c0a794e1 fix(GuildAuditLogsEntry): default to object with id for deleted targets (#3373) 2019-08-28 11:22:25 +02:00
izexi
2a3fb705d0 fix(ChannelStore): return existing DMChannels within add() (#3438)
* fix: return existing DMChannels

* ref: group nested conditions
2019-08-28 11:13:09 +02:00
didinele
745a0ea942 typings(DataStore): correct return types for resolve, resolveID and remove (#3448)
* fix(typings): DataStore#resolve & DataStore#resolveID can also return null.

* fix(typings): DataStore#remove returns a boolean, not void.

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>
2019-08-28 11:11:15 +02:00
Ryan Munro
dcee09c308 backport(Permissions): backport STREAM permission from #3309 (#3447)
* Backport the STREAM permission

* Update typings and default
2019-08-28 11:09:45 +02:00
Gryffon Bellish
4c08812302 docs(ClientOptions): document unit of restRequestTimeout (#3449) 2019-08-26 18:52:30 +02:00
iCrawl
8bbf1a9228 ci: remove leftover docs action 2019-08-25 07:45:45 +02:00
iCrawl
6baff9e3fc ci: change job name for docs 2019-08-24 22:26:08 +02:00
iCrawl
08dfdcb4eb ci: deploy docs using new action 2019-08-24 22:17:40 +02:00
iCrawl
57033f3334 ci: add npm install steps 2019-08-24 20:31:12 +02:00
iCrawl
fd49082ac0 ci: run ci in parallel 2019-08-24 20:28:44 +02:00
iCrawl
1511e96761 ci: run docs excluding 2019-08-24 19:45:52 +02:00
iCrawl
4f9e7f4a23 ci: remove travis 2019-08-24 19:32:40 +02:00
Crawl
e8451561ed ci: github actions (#3442)
* feat: eslint action

* refactor: actions v2

* fix: set +x for entrypoint

* ci: integrate docs

* fix: give it a nice name

* ci: publish docs

* ci: fix yaml key error

* ci: fix executable

* ci: use normal sh shebang

* ci: move into the workspace

* ci: fix eslint path

* ci: manually run the build

* ci: use different container

* ci: install git

* ci: assume yes flag

* ci: use correct branch

* ci: fix branch and source

* ci: fix condition

* ci: remove useless steps

* ci: rename action

* ci: make executable again

* ci: cleanup

* ci: add stable branch

* ci: remove semi

* ci: do some logging for failing action

* ci: remove actions api

* ci: re-add semi

* ci: use actions repo

* ci: use v1 tags

* ci: remove semi

* chore: change job name passed to eslint

* chore: dummy commit, remove different semi

* ci: change job name

* chore: dummy commit

* ci: add gh-actions as possible branches

* ci: lint all branches

* ci: dummy

* ci: separate pr and push

* chore: run actions on gh branch

* ci: try excluding branches
2019-08-24 19:32:18 +02:00
Amish Shah
c715ed9f8b voice: remove passes
(discord will begin dropping duplicated audio packets from tomorrow, you should not set passes > 1)
2019-08-22 12:15:20 +01:00
Carter
cc488a8bd3 fix: GuildMemberStore#_fetchMany (#3420)
* added DARK_MODE_INVISIBLE

added another constant color that makes embeds appear invisible on DARK mode.

* travis likes trailing commas

* fix: ref issue: #3414

* fix: removed a random color
2019-08-21 16:52:08 +01:00
Vlad Frangu
5e4f9d436d src: alphabetize guild features and make sure they're up to date (#3441) 2019-08-21 12:52:35 +01:00
Vlad Frangu
fbd811517a src: Update Webhook#sendSlackMessage to be accurate with what the API returns (#3429)
* src: Update sendSlackMessage

* typings
2019-08-19 21:02:33 +01:00
Saya
e4309b23d5 feat: abort Requests that takes a lot of time to resolve (#3327)
* Add Request Timeout

* Add abort controller in packages

* Fix Lint Error.

* Fix Lint Errors

* Make Timeout Customizable & use finally

* Fixed a minor issue

* Fix eslint

* Update request timeout to use d.js client timeout methods.
2019-08-19 18:55:07 +02:00
neoney
3fcc862c5f docs: fix voice broadcast example code (#3436)
client.createVoiceBroadcast() -> client.voice.createBroadcast()
2019-08-18 11:54:30 +02:00
SpaceEEC
c786867bd6 fix(Webhook): return raw data if the channel is unavailable
Fixes #3424
2019-08-18 11:45:28 +02:00
Khoo Hao Yit
1851f74770 fix(ReactionUserStore): remove method firing messageReactionRemove event twice (#3277) 2019-08-17 21:09:29 +02:00
Koyamie
12b48b7cbb fix(GuildMemberRoleStore): correctly reference the everyone role (#3434) 2019-08-17 20:57:14 +02:00
izexi
d62db232e7 feat(Invite): add targetUser(Type) (#3262)
* add Invite#targetUser(Type)

* incase discord decides to add 0
2019-08-17 20:31:04 +02:00
Khoo Hao Yit
8ae7a30d0b fix(Message): delete method caused messageDelete event to fire twice (#3252)
* ref: add getPayload and use for other get* methods

* return existing data.*

* use Action.getUser()

* Fix messageDelete double emission
2019-08-17 19:33:03 +02:00
Gryffon Bellish
ab27dd0218 refactor(TeamMember): remove client from constructor (#3409)
* Remove client from TeamMember constructor part 1

* Remove client from TeamMember constructor part 2

* update typings
2019-08-17 18:24:16 +02:00
BannerBomb
b662678f21 feat/fix(Util): fix animated part of parseEmoji regex and make id optional (#3407)
* Small changes to parseEmoji regex

I just made a small change to the parseEmoji regex, this change will make an invalid emoji, like `<aname:id>` return as null, before this change it would return as an animated emoji because the name started with an `a` which would result in false positives, then the `?` I added to the end of `(\d{17,19})?` is used if someone provided an emoji as `:name:` or `a:name:` it will return the correct values but have an invalid id.

* Update Util.js

2nd Update: I changed the regex to output the results if you provide `<aemoji:123456789012345678>` and <:aemoji:123456789012345678>` which will output `{ animated: false, name: "aemoji", id: "123456789012345678" }` or `<:emojiname:>` which outputs `{ animated: false, name: "emojiname", id: null }` or `<a:emoji:>` which would output `{ animated: true, name: "emoji", id: null }`. Before this PR the method would return that the emoji was animated if you provided something like `<anemojiname:emoji_id>` because the name started with an `a`.
2019-08-17 18:07:58 +02:00
didinele
2df4f227a4 refactor: move Guild#defaultRole to RoleStore#everyone (#3347)
* remove guild#defaultRole

* add RoleStore#defaultRole

* typings

* fix trailing space

* another one

* Rename it to everyone
2019-08-17 18:02:17 +02:00
bdistin
6d3c55b68c feat(Collector): allow collectors to be consumed by for-await-of loops (#3269) 2019-08-17 17:57:45 +02:00
Carter
7fae6e5bca typings: switch overloads of RoleStore#fetch (#3397)
because compu told me to
2019-08-17 17:51:52 +02:00
Robin Millette
f55e4302c9 github: fix duplicate key in FUNDING.yml (#3380)
Comment out (keep for reference) unused platforms. Also fixes a duplicate `github` key.
2019-08-17 17:50:49 +02:00
Amish Shah
c6e8fccbf0 voice: fix #3418
(kicking bot from voice channel doesn't allow it to rejoin)
2019-08-17 13:42:22 +01:00
Amish Shah
2c4d14a71b voice: remove redundant debug info 2019-08-14 19:22:41 +01:00
Amish Shah
f79f024343 fix: bots being unable to connect 2019-08-12 21:40:26 +01:00
Vlad Frangu
9e76f23314 fix(GuildMemberStore): reject BAN_RESOLVE_ID error instead of throwing it (#3425) 2019-08-10 12:22:11 +02:00
iCrawl
d14db52158 fix(typings): send overloads 2019-08-04 15:57:39 +02:00
SpaceEEC
1121b2f7bf fix(GuildChannel): return GuildChannel in setPosition instead of Guild
fixes #3413
2019-07-30 17:46:22 +02:00
Crawl
5af8cb8e6e feat: overload for split always returning an array (#3411)
* feat: overload for split always returning an array

* feat: update Util.splitMessage
2019-07-30 00:25:45 +02:00
TNThacker2015
e645dd6358 feat: Util.splitMessage always return an array (#3035)
* Making Util.splitMessage always return an array

Util.splitMessage sometimes returns an array, but other times it returns a string. This should make it so that it always returns an array.

* jsdoc

Co-Authored-By: TNThacker2015 <37024464+TNThacker2015@users.noreply.github.com>

* docs(Util): remove superfluous space in docstring
2019-07-30 00:25:35 +02:00
Lewis
53722b47c1 chore(license): update copyright notice (#3408) 2019-07-30 00:00:56 +02:00
Alex
e562564123 docs(Guild): add missing features (#3406)
* Update Guild.js

* Update Guild.js

* style(Guild): remove trailing space

* typings(Guild): add new features
2019-07-28 15:24:27 +02:00
Kitten King
d8516efa36 docs: fix typos (#3404) 2019-07-25 17:18:23 +02:00
Crawl
651ff81bd5 fix: update issue templates 2019-07-13 18:02:07 +02:00
MoreThanTom
547bf83100 feat(typings): constants export (#2915)
* Added typings for Constants export

* Full typing of list Constants

* Fix mistake in Package typing

* Cleanup for requested changes

moved fs import to import cluster
WSEvents using WSEventType to build type

* Satisfy tslint rules

* Update Constants.js

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts

* Update index.d.ts
2019-07-12 17:02:45 +02:00
bdistin
00c4098bb3 refactor(Util.escapeMarkdown): allow separate escaping and add tests (#3241)
* wip refactor

* add escapeMarkdown tests

* italics can be done with a single underscore too

* more refined

* fix test name

* unnecessary eslint ignores

* use jest

* make eslint less annoying in this test file

* more testing

* fix lib usage

* more tests and a small fix
2019-07-11 22:08:40 +02:00
Eduardo Londero
f1433a2d97 feat(Collector): add idle time for a Collector to stop itself (#2942)
* Implement idle feature

* Add typings

* Minimal fixes

* Make everything in Collector and not attached to ReactionCollector

* set this._idletimeout to null when collector ends

* also set this._timeout to null when collector ends
2019-07-11 21:40:12 +02:00
SpaceEEC
0cd7556934 feat(Teams): backport support for teams (#3357)
* feat(Teams): backport support for teams

PR #3350
Commit: a22aabf6a8

* fix(TeamMember): fix name of client property

* refactor(OAuth2Application): make team nullable instead of optional

* typings(OAuth2Application): make team nullable instable of optional

* docs(OAuth2Application): deprecate and add an info to team property
2019-07-11 13:10:54 +02:00
Jisagi
adb082305d feat(Guild): add banner to edit method and add setBanner method (#3364)
* add setBanner method to Guild

* typos fixed & typings added

* more typings

* docs(Guild): add banner to GuildEditData
2019-07-11 13:09:43 +02:00
Vlad Frangu
4069d009d1 misc: automatically add labels to issues that use a template (#3367)
* misc: Automatically add labels to issues that use the template

* misc: Ditto

* misc: DITTO
2019-07-11 12:59:19 +02:00
Skillz4Killz
20d7b3de59 docs/typings(VoiceStateStore): document and type the class (#3294)
* Update index.d.ts

* Update Guild.js

* Update Guild.js

* docs/typings(VoiceStateStore): document and add typings
2019-07-04 16:20:28 +02:00
SpaceEEC
b65a4f05da fix(ClientApplication): fix ternaries 2019-06-26 20:19:05 +02:00
SpaceEEC
1dd4c041e0 fix(ClientApplication): owner is still nullable
Fixes #3358
2019-06-26 20:12:05 +02:00
SpaceEEC
4c11347511 docs(Team*): fix appliction -> team, tag -> mention 2019-06-26 11:42:03 +02:00
Vlad Frangu
61e2e3e1ad docs: add zucc to docsite welcome page (#3355) 2019-06-26 11:36:11 +02:00
SpaceEEC
d7b2146c81 refactor(TeamMember): make id a getter 2019-06-25 20:40:15 +02:00
bdistin
a22aabf6a8 feature: teams support (#3350)
* basic teams support

* export Team & TeamMember

* use typedef

* typings and some fixes

* Update src/structures/TeamMember.js

Co-Authored-By: Vlad Frangu <kingdgrizzle@gmail.com>

* fix Team#iconURL()

* fix typings and a bug

* fix states start at 1

* team icon hash can be null

* fix owner typings
2019-06-25 20:31:48 +02:00
anandre
6100aceef2 docs(RoleStore): update -> create in create method (#3349)
Under `create`, change `update` -> `create` in the description
2019-06-19 18:49:33 +02:00
SpaceEEC
c355236f7f feat(Emoji): backport delete method (#3343)
This backports #1877 (c93c4ad21f) in a semver-minor manner.
2019-06-16 10:07:32 +02:00
SpaceEEC
b8924369ea feat(Guild): add support for premium/boosting (#3332)
Backports:
PR: #3316
Commit: c87758086b
2019-06-13 19:03:36 +02:00
SpaceEEC
e6a378b361 feat(Guild): backport misc properties and setRolePositions (#3337)
* feat(Guild): backport misc properties and setRolePositions

PRs:
* #3168
* #3317

* typings
2019-06-13 18:33:07 +02:00
SpaceEEC
1bec28bd81 feat(Guild): default iconURL to gif if animated (#3338)
* feat(Guild): default iconURL to gif if animated

* Icon, not Banner

* fix url
2019-06-13 14:14:47 +02:00
Ryan Munro
f82f0af928 docs(Presence): document client property (#3342) 2019-06-12 21:54:12 +02:00
SpaceEEC
6cd4c27fae docs(Client): fetchVoiceRegions returns a promise 2019-06-08 16:18:50 +02:00
SpaceEEC
6f49aadf4f fix(Guild): allow fetchMember to be used with an uncached user (#3333) 2019-06-08 10:39:03 +02:00
Alex
19ef45130b docs(Guild): add missing features (#3336)
The addition of missing guild features that were added in the Nitro boost update, such as ANIMATED_ICON
2019-06-08 10:38:45 +02:00
SpaceEEC
4a2335c69c docs(*Resolvable): make them appear on the docs
I don't know what part of the docgen is not working properly, but this seems to fix those typedef
to not appear on the documentation
2019-06-05 22:18:06 +02:00
SpaceEEC
8e1857286d typings(Guild): add typings for setRolePositions
See:
PR: #3317
Commit: 8bc8ffe168
2019-06-05 22:18:01 +02:00
brian
8bc8ffe168 feat(Guild): add setRolePositions method(#3317)
Allows for role positions to be batch-updated similar to how channel
positions are. It uses the Discord API endpoint PATCH /guild/:id/roles
2019-06-05 21:57:31 +02:00
Skillz4Killz
e87e4a6f0e typings(GuildChannelStore): add CategoryChannel as possible return value (#3326) 2019-06-05 21:46:11 +02:00
Saya
ddcc6cfec9 docs(Constants): add missing GUILD_EMOJIS_UPDATE to WSEvents (#3325) 2019-06-05 21:37:10 +02:00
izexi
c87758086b feat: add support for premium guilds (#3316)
* add premiumTier and premiumSubscriptionCount

* add premiumSinceTimestamp and premiumSince

* add premium message types

* typings

* add GuildEmoji#available

* fix doc description
2019-06-05 21:34:33 +02:00
Gryffon Bellish
0c6101901d fix(docs): backport documentation for Presence#clientStatus (#3315)
* backport documentation for Presence

* capitalize o

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* remove extra space

* backport ClientPresenceStatus

* Change to Client Presence Status
2019-06-01 20:24:22 +02:00
Deivu (Saya)
405bdb5b55 cleanup(Constants): remove duplicate VOICE_STATE_UPDATE (#3313) 2019-05-31 09:06:28 +02:00
DeJay
5aa9425040 Removes the trace packet (#3312)
* Removes the trace packet

* Update src/client/websocket/WebSocketShard.js

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>

* Update src/client/websocket/WebSocketShard.js

Co-Authored-By: Amish Shah <amishshah.2k@gmail.com>
2019-05-30 19:57:34 +01:00
bdistin
5154850a54 Add Stream permission (#3309)
* Add Stream permission

* update docs, and DEFAULT

Created a new guild to test DEFAULT

* update typings
2019-05-30 08:26:49 +01:00
Amish Shah
5dd9181497 v11.5.1 2019-05-29 21:23:16 +01:00
SpaceEEC
db492e66e2 chore: explicitly mark everything deprecated as @ deprecated (#3307) 2019-05-29 22:18:14 +02:00
Amish Shah
8652e47c14 fix: decode voice ws data as json 2019-05-28 14:51:41 +01:00
Amish Shah
b5aff6d120 remove member voice state after emitting leave event 2019-05-28 10:00:57 +01:00
Will Nelson
d34b62414b fix: StreamOptions#volume typings (#3303) 2019-05-27 20:56:40 +01:00
Gus Caplan
065908956b fix websocket unpacking (#3301) 2019-05-27 18:13:25 +01:00
Amish Shah
db56e0cbae fix: delete VoiceStates even for uncached members 2019-05-27 18:09:54 +01:00
Amish Shah
949488bbbd Fix #3218 2019-05-27 14:04:13 +01:00
Amish Shah
1ce670daa9 Create FUNDING.yml
Just trialling it out
2019-05-26 10:33:58 +01:00
Will Nelson
9ca36b8eea typings(VoiceState): add connection getter (#3292)
* fix: add connection to voice state typings

* Update typings/index.d.ts

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>
2019-05-25 16:18:44 +02:00
izexi
3f1232ebf3 feat: throw custom error for uncached Guild#me (#3271)
* handle cases where Guild#me is uncached

* fix id prop

* remove unnecessary checks

* space's requested changes
2019-05-25 13:50:32 +02:00
anandre
34006cb51e docs(StreamDispatcher): specify pausedTime is in milliseconds (#3295)
* Update TextChannel.js

Update `setRateLimitPerUser` description to specify the `number` is in seconds, per the Discord docs

* Update TextChannel.js

Add unit to the rateLimitPerUser property

* Update GuildChannel.js

* Update StreamDispatcher.js

Specify unit for `StreamDispatcher.pausedTime`
2019-05-24 20:33:40 +02:00
SpaceEEC
97f3b6c5eb typings(Guild): remove voiceConnection, add voice, cleanup rest
Fixes #3293
2019-05-24 15:42:09 +02:00
Antonio Román
b3060ea229 typings(Collection): use T in accumulator and initialValue when reducing (#3284)
This brings some consistency with Array#reduce's typings and to reality.
2019-05-20 20:49:28 +02:00
bdistin
8c213e9088 fix(Message#pinnable): you can't pin system messages (#3279) 2019-05-18 19:06:15 +02:00
bdistin
abebeac193 fix(Message#pinnable): you can't pin system messages (#3279) 2019-05-18 19:02:23 +02:00
SpaceEEC
06b72ee19f fix(GuildMember): do not create a channel key when editing
This is to not break GuildMember#setNickname for the current user
2019-05-18 14:08:50 +02:00
SpaceEEC
3ad16fa351 fix(GuildMember): do not create a channel key when editing
This is to not break GuildMember#setNickname for the current user
2019-05-18 14:08:12 +02:00
didinele
97de79bd5e fix(typings): Guild#member can return null (#3274)
* fix(typings): Guild#member did not have undefined as a return type

* oops, it can apparently return null
2019-05-16 21:14:45 +02:00
SpaceEEC
1bafa4b86b fix(READY): do not overwrite Client#user when reidentifying
See #3216, this commit attempts to fix losing ClientUser#_typing, which results in no longer being able to clear typing intervals
2019-05-16 19:56:19 +02:00
Fong Jian Ping
e3d03adcf8 docs(ChannelCreationOverwrites): revert incorrect rename of "id" property (#3273)
Reverts one incorrect change made in #2734 (3021e5ce7f (diff-e5c54069adfa0d32480eb3cc9faeee20L979))

* Fix incorrect docs in Guild.js

* Update src/structures/Guild.js

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* Update Guild.js
2019-05-16 13:06:07 +02:00
anandre
363cec31bc docs(TextChanne): specify unit of rateLimitPerUser (#3272)
* Update TextChannel.js

Update `setRateLimitPerUser` description to specify the `number` is in seconds, per the Discord docs

* Update TextChannel.js

Add unit to the rateLimitPerUser property

* Update GuildChannel.js
2019-05-15 22:42:39 +02:00
anandre
55447fd4da docs(TextChanne): specify unit of rateLimitPerUser (#3272)
* Update TextChannel.js

Update `setRateLimitPerUser` description to specify the `number` is in seconds, per the Discord docs

* Update TextChannel.js

Add unit to the rateLimitPerUser property

* Update GuildChannel.js
2019-05-15 22:33:27 +02:00
SpaceEEC
16fcfa3db3 fix(WebSocketManager): rethrow unknown errors when connecting a WebSocketShard 2019-05-15 22:13:12 +02:00
SpaceEEC
c844a7b4e2 docs(Guild): fix typo in example of createChannel 2019-05-14 20:12:57 +02:00
Amish Shah
72dd872fce VoiceBroadcast.{dispatchers -> subscribers} 2019-05-12 20:29:28 +01:00
Schuyler Cebulskie
e82633fb00 Bump version to 11.5.0 2019-05-11 19:05:10 -04:00
Schuyler Cebulskie
b2f89e4594 Add testing for Node.js 8-12 2019-05-11 19:00:03 -04:00
Schuyler Cebulskie
8fba786765 Update typings for news/store channels 2019-05-11 18:56:14 -04:00
Schuyler Cebulskie
43f2485c9c Document news/store channel types on Guild#createChannel 2019-05-11 18:11:34 -04:00
Schuyler Cebulskie
8a086e04ab Add news/store channel support to CHANNEL_CREATE 2019-05-11 18:11:19 -04:00
Schuyler Cebulskie
f30019dd4f Remove unnecessary import 2019-05-11 17:24:25 -04:00
Schuyler Cebulskie
5e4654ee07 Backport news/store channels 2019-05-11 14:58:46 -04:00
izexi
75d5598fda import TextDecoder from Util (#3258) 2019-05-08 21:03:18 +01:00
izexi
0dd3ed72ef fix(Partials): Client#event:messageUpdate(oldMessage) and MessageReactionAdd on guild channels (#3250)
* ref: add getPayload and use for other get* methods

* return existing data.*

* use Action.getUser()
2019-05-07 20:56:39 +01:00
Gus Caplan
3d4513268d Add optional zstd for faster WebSocket data inflation (#3223)
* zstd
2019-05-07 14:30:34 +01:00
Darqam
8915bc1d37 docs:(Client): disambiguate the description of channels collection (#3251)
* Disambiguate the description of <client>.channels

Although not explicitly said, the current wording makes it seem like all channels are cached and available at any time in this store. Hopefully this variation makes it a bit clearer.

* make more explicit (I think)

* remove trailing white spaces
2019-05-06 20:08:56 +02:00
SpaceEEC
ee42bdfd76 feat(GuildMember): add support for voice kicking (#3246)
This backports e64773e21b (#3242)
2019-05-06 19:18:29 +02:00
SpaceEEC
67da457c0a fix/docs(Client): type status and do not throw an error if accessed before login 2019-05-05 13:44:34 +02:00
SpaceEEC
60013b7a10 fix(WebSocketConnection): stringify data when no websocket is available
[object Object] is not really descriptive
2019-05-04 21:00:49 +02:00
SpaceEEC
8b83e2fdcb typings(Presence): add missing guild property 2019-05-04 19:05:04 +02:00
Amish Shah
e64773e21b Add ability to kick members from VoiceChannels and remove duplicated methods (#3242)
* feat(voice): kick members from voice channels

* fix(VoiceState): improve stability in checking for client user

* feat(VoiceState): add setChannel for moving/kicking members

* update typings

* remove duplicated methods across GuildMember and VoiceState

member.setDeaf => member.voice.setDeaf
member.setMute => member.voice.setMute
member.setVoiceChannel => member.voice.setChannel
2019-05-04 16:46:42 +01:00
Amish Shah
d7f8fd1ae0 fix #3244 2019-05-04 16:21:49 +01:00
izexi
176fc47699 feat(Actions): use partials for messageDeleteBulk (#3240)
* make use of partials

* don't cache the messages

* pass each message within the for..of iteration
2019-05-03 17:38:57 +02:00
Jacz
692494dc04 feat(VoiceState): self mute/deaf methods (#3243)
* Implemented setSelfMute/Deaf, done typings, fixed bug in VoiceState with errors.

* Completed requested changes

* return send in sendVoiceStateUpdate so its a promise, update typings

* Updated methods to return a boolean

* Requested changes

* Fix bug

* Update src/structures/VoiceState.js

Co-Authored-By: MrJacz <23615291+MrJacz@users.noreply.github.com>

* fix
2019-05-03 17:11:11 +02:00
Vlad Frangu
a59968f7de src: add news and store channels, and missing guild props (#3168)
* src: Implement store and news channels!

* src: Remove code dupe

* src: Add missing guild properties

* docs: Add a small notice that the channel type may also change

* src: Remove re-creation of the MessageStore

* lint: Unused Import

* src: Requested changes for StoreChannels

* typings: Fix typings

* src: Moar guild updates

* src: Set maximumPresence to the data prop, the already existent one, or default to 5000

* typings: afkChannel is a VC

I keep confusing them, ffs

Co-Authored-By: vladfrangu <kingdgrizzle@gmail.com>

* docs: Document that maximumMembers and maximumPresences may be inaccurate before fetching

* src Appels requested changes
2019-05-03 17:08:07 +02:00
Amish Shah
0d9bc8664d voice: make Guild.voice more robust 2019-04-29 19:31:31 +01:00
Amish Shah
bcb0cd838b voice: remove Guild.voiceConnection and VoiceChannel.connection 2019-04-29 19:29:16 +01:00
Amish Shah
dd44647537 voice: Guild.voiceConnection => Guild.voice.connection 2019-04-29 19:24:27 +01:00
Amish Shah
ce1e3d2084 feat(VoiceConnection): add .voice 2019-04-29 19:13:41 +01:00
bdistin
2666a9d6db feat(MessageStore): add remove() (#2468)
* MessageStore#remove()

* typings
2019-04-29 17:53:32 +01:00
Vlad Frangu
d7a9b74523 src: Replace instanceof Array checks with Array.isArray and instanceof Buffer with Buffer.isBuffer (#3227)
* src: Replace instanceof Array checks with Array.isArray

* src: Buffer.isBuffer instead of instanceof Buffer
2019-04-29 17:49:41 +01:00
bdistin
9b0f4b298d feature: public raw events (#3159)
* add a public alternative to the private raw event

while retaining raw for use in debugging privately

* only emit dispatch packets

* requested changes

TIL, that's neat

* fix padding

* requested changes

* Update WebSocketManager.js
2019-04-29 17:37:57 +01:00
izexi
870528ed33 feat(VoiceChannel): add editable (#3173)
* add VoiceChannel#editable

* replace unnecessary super with this

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>
2019-04-29 17:35:48 +01:00
izexi
23191da13d feat(Partials.GuildMember): GuildMemberRemove & Guild#me (#3229)
* use partials for GuildMemberRemove & Guild#me

* oops

* guild.members instead of Action.members

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>
2019-04-29 17:05:52 +01:00
Vlad Frangu
bc31746621 src: Client#readyAt should be updated when triggerReady is called (#3234) 2019-04-29 17:03:29 +01:00
Crawl
aa253d9551 fix(ClientUser): lint 2019-04-28 13:14:26 +02:00
Amish Shah
4e0cf87d0f fix: typing map being reset for ClientUser (#3216) 2019-04-27 18:52:26 +01:00
Amish Shah
e0cfb7fb36 fix: not checking for guild when creating a channel 2019-04-27 13:39:23 +01:00
Amish Shah
4d7fc036a1 fix: channels being removed from guild.channels 2019-04-27 11:46:48 +01:00
Vlad Frangu
577636a46d src: fix random broken reconnects (#3233) 2019-04-27 08:25:24 +01:00
Vlad Frangu
de79bba965 src: Fix type error in WebSocketShard#onError (#3231) 2019-04-24 16:53:41 +02:00
izexi
7b531648e0 feat(GuildMemberStore) add options.count to prune (#3189)
* add GuildMemberStore#prune(options.count)

* typings: proper typings for null return value
2019-04-23 21:59:52 +02:00
SpaceEEC
39115c8acc fix(MessageCreateAction): remove redundant GuildMemberStore#add call
This was also causing a bug where GuildMember#_roles was patched with a GuildMemberRoleStore
2019-04-23 21:21:41 +02:00
SpaceEEC
6a07715c1d fix(Guild): only update emojis when they are present in the payload 2019-04-23 21:02:16 +02:00
Vlad Frangu
75cd260808 src: Don't use the GuildMemberRoleStore to patch the GuildMember _roles (#3226)
* src: Don't use the GuildMemberRoleStore for patching GuildMember#_roles

* src: Remove usage of _patch from the store

* src: Finish up clone changes
2019-04-23 19:44:02 +01:00
didinele
3f6d08a499 fix(typings): Collection#find & findKey can return undefined (#3228)
* fix(typings): [Collection#find](https://github.com/didinele/discord.js/blob/master/src/util/Collection.js#L172) can also return undefined

* same thing for findKey
2019-04-23 18:47:42 +02:00
Amish Shah
23e6414420 fix: old objects not being cached (#3225)
please post issues if you find any, will probably cause some
2019-04-23 11:32:03 +01:00
izexi
c4b79571ba feat(Invite): add deletable getter (#3203)
* add Invite#deletable

* fix ci

* reee

* since guild is nullable

* accommodate for external invites

* nit(Invite): use guild instead of channel.guild
2019-04-22 09:24:32 +02:00
izexi
f7f4607b5f docs(faq): bump to node 10.0.0 (#3224) 2019-04-22 09:09:06 +02:00
anandre
d1778772cd docs: update node version requirement, npm install links, add update guide (#3220)
* Update welcome.md

Update node version requirement, npm install links, docs links, made a note that the guide is for stable and added a new link to the WIP update guide.

* docs(welcome.md): put notice for wip update guild on its own line

* docs(welcome.md): indent own line

* docs(README.md): apply the same changes here
2019-04-21 13:47:09 +02:00
Antonio Román
01c708bc75 feat(Sharding): change waitForReady to spawnTimeout (#3080)
This means that you'll not only be able to choose between having a timeout or not, but also to set the amount of milliseconds as you wish.
2019-04-21 13:34:09 +02:00
Purpzie
abd9d36816 feat(Util): resolve text parameter of splitMessage to a string (#3212) 2019-04-21 09:38:09 +02:00
Dragoteryx
52b4f09e58 fix(Structures): allow multiple extensions by checking prototype chain (#3217) 2019-04-21 09:34:12 +02:00
Vlad Frangu
1514df0f87 fix: emit resume event, silent disconnects, error event param (#3192)
* src: Fix shardResumed event not being emitted

* docs: Document Client#error again

* src: Fix onError due to incorrect typings

* src: handle onError properly for both uws and ws

* src: Try to fix silent disconnects when using uWs

* fix(WebSocketShard): uws emits plain objects, not errors

Emitting line of code: 39aa429f94/src/uws.js (L80-L83)
Listener attaching is here: https://github.com/discordjs/uws/blob/master/src/uws.js#L128
For reference, found a clue here: https://github.com/discordjs/discord.js/issues/1528
2019-04-21 09:32:16 +02:00
SpaceEEC
cde955c766 fix(PresenceUpdateAction): emit presences again (#3214)
* fix(PresenceUpdateAction): emit presences again

* update typings
2019-04-19 08:49:17 +02:00
Gryffon Bellish
bccbb550b0 docs(Collector): specify the unit for CollectionOptions#time (#3219) 2019-04-19 08:47:39 +02:00
SpaceEEC
12e041bc2b typings(GuildChannel): add manageable getter 2019-04-17 21:39:46 +02:00
Deivu (Saya)
b5320299f7 Only reset sessionID when close code is 1000 or 4006 (#3213)
* Event code 1001 should not get its sessionID reset

* Reset sessionID when close code is 1000 or 4006
2019-04-17 14:32:57 +01:00
izexi
39fd8fd645 fix(typings): remove duplicated Guild#defaultRole (#3211) 2019-04-16 22:14:01 +02:00
izexi
0b1176d9a1 chore(typings): declaring explicit nullable returns (#3134)
* strict nullable & WebSocketManager private typings

* missing semicolon

* kyra suggestion #1

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* kyra suggestion #2&3

* space's requested changes

* space's requested change

* strict nullable & WebSocketManager private typings

missing semicolon

kyra suggestion #1

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

kyra suggestion #2&3

space's requested changes

space's requested change

* resolve conflicts

* deflate
2019-04-15 21:01:39 +02:00
MoreThanTom
52bc5b0170 feat(MessageEmbed): resolve color in embed constructor (#2912)
* Resolve color in embed constructor

* Use ColorResolvable type for color parameter

* docs(MessageEmbed): color property is still a number
2019-04-15 20:46:59 +02:00
Vlad Frangu
eb537b6f48 docs(WebSocketShard): mark non-nullable parameters as non-nullable (#3209)
* docs: Imagine having an optional nullable param

* docs: Another one
2019-04-15 20:17:27 +02:00
izexi
d9a053df67 docs(Presence): add ClientPresenceStatus typedef (#3208) 2019-04-15 14:41:37 +02:00
izexi
3cd224dc76 docs(Collection): fix findKey jsdoc (#3204) 2019-04-14 15:49:32 +02:00
danielnewell
2af101efbb docs(faq): add a link to the guide, restructure a bit (#3082)
* Update faq.md

added link to guide

* docs(faq): link documentation as per suggestion
2019-04-14 15:47:52 +02:00
Isabella
cbb9b14950 test: add Webhook(Client) testing file (#2855)
* test: add WebhookClient testing file

* webhooks cant edit messages, silly

* add more webhook types as requested

* fix typo

* eslint matters

* fix(webhooktests): add 'use strict', remove embed: tests
2019-04-14 15:27:59 +02:00
izexi
520810d484 feat(Util): add YELLOW to ColorResolvable (#3182) 2019-04-14 14:58:33 +02:00
SpaceEEC
ca43919642 docs: document constructors of extendible structures (#3160)
* docs: document constructors of extendible structures

* docs(ClientPresence): document default value for data parameter

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* docs(Presence): document default value for data parameter

Co-Authored-By: SpaceEEC <spaceeec@yahoo.com>

* docs(DMChannel): capitalize DM in the constructor doc
2019-04-14 14:50:55 +02:00
izexi
5d10585af8 docs(Presence): add missing descriptions to clientStatus (#3127)
* add description on jsdocs for User.clientStatus

* Update src/structures/Presence.js

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* Update src/structures/Presence.js

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* Update src/structures/Presence.js

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* update typings
2019-04-14 14:43:01 +02:00
SpaceEEC
97c196ca6a docs(GuildEmoji): add @ name to requiresColons and managed properties 2019-04-13 19:32:43 +02:00
thomasxd24
8da141637c fix end method in VoiceBroadcast (#3194)
* fix end method in VoiceBroadcast

this.client is a ClientVoiceManager and thus its this.client.broadcasts  instead of this.client.voice.broascasts

* revert the voicebroadcast and pass this.client at clientvoice

* passed this.client
2019-04-11 21:34:12 +01:00
izexi
62cba2e148 docs(GuildChannel): fix setPosition's reason type (#3199) 2019-04-11 10:10:31 +02:00
anandre
266ac1c659 docs(Role): fix setPosition's reason type (#3198) 2019-04-10 21:40:22 +02:00
Reseq64
6be5051f92 typo(RequestHandler): fix spelling of 'requests' (#3196)
Removed the additional "s" to "requessts"
2019-04-10 17:07:50 +02:00
Vlad Frangu
89e27e5071 src: Make broadcasts work again (#3190) 2019-04-08 17:29:19 +01:00
SpaceEEC
f479afca82 src: Fix TypeError (#3187) 2019-04-08 14:21:48 +02:00
Vlad Frangu
70d4b4455b refactor(ClientVoiceManager): make public, remove Client#voiceConnections (#3186)
* docs: make voice public

* typings: Update typings to match the docs

* typings: ClientVoiceManager is nullable in Client

Co-Authored-By: vladfrangu <kingdgrizzle@gmail.com>

* typings: Mark client as readonly

Co-Authored-By: vladfrangu <kingdgrizzle@gmail.com>

* src: Make the client readonly

* src: Remove Client#voiceConnections getter in favor of ClientVoiceManager#connections
2019-04-08 14:20:53 +02:00
SpaceEEC
923c945b4b fix(Guild): sort roles with the same position in the correct order (#3184) 2019-04-08 14:06:50 +02:00
izexi
152d2e88bd refactor(WebSocket): utilize URLSearchParams (#3185)
* replace querystring with URLSearchParams

* looks a bit nicer using urlSearchParams.set(...)
2019-04-08 14:06:23 +02:00
Vlad Frangu
982f48ce6a src: Fix TypeError 2019-04-07 10:57:11 +03:00
SpaceEEC
00eb7e325a fix(ApiRequest): filter out null query values
Fixes #3183
2019-04-05 16:32:50 +02:00
SpaceEEC
bfab203934 fix(ShardingManager): do not spawn the last shard early
An off-by-one error resulted in the last shard getting the delay of the second last one.
Closes #3181
2019-04-05 14:46:25 +02:00
bdistin
5e9bd786d1 refactor(APIRequest): utilize URLSearchParams (#3180)
* utilize URLSearchParams

* options.query can be undefined/null

* oops

* remembered what I intended
2019-04-05 11:32:19 +02:00
izexi
c078682722 feat(Webhook): add url getter (#3178)
* add Webhook#url

* set typing as readonly

* suggested change

* another one
2019-04-05 11:09:58 +02:00
bdistin
bb92289e45 fix: remove GuildChannel fallback, and remove GuildChannel as extendable (#3165)
* remake pr

* typings
2019-04-03 23:02:19 +02:00
SpaceEEC
089f65fd2a fix(RequestHandler): pass HTTPError pass path instead of route as path 2019-04-03 22:45:51 +02:00
SpaceEEC
32a432f4a5 cleanup(ShardClientUtil): rename id to ids 2019-04-01 13:46:27 +02:00
Vlad Frangu
3f5161eb76 fix: Internal Sharding, this time fixed™ (#3140)
* src: WIP Internal Sharding refactor

* src: Refactor unavailable guild check
Co-Authored-By: kyranet <kyradiscord@gmail.com>

* src: More WIP Code
F in the chat to the old manager

* src: It should work but Discord says no.
Seriously why is this not working!

* fix: Inflator causing issues

* src: Finishing touches and typings

* misc: Proper debug message

* fix: Making things hidden needs writable: true as well

* fix: Sharding allowing multiple of the same shard, negative shards or strings

* fix: Again... edge cases
I love you guys .w.

* misc: Touchups

* misc: Better error?

* docs: Typo

* typings: Requested changes

* src: Requested changes

* src: Fix issues, validate provided shard options and more

* src: Forgot to remove the listener

* lint: eslint complaining

* fix: Setting shardCount to auto crashing the process

* misc: Requested changes

* typings: Correct typings for shardCount client option

* typings: Add invalidSession event to the shard and correct typings

* src: Minor docs adjustements, and code consistency between setHelloTimeout and setHeartbeatTimeout

* src: Don't block reconnect while creating shards
Might fix silent disconnects *again*

* src: Prevent reconnect from running if the Manager isn't READY
That way, if a shard dies while we're still spawning, it won't cause issues

* fix: Retry to reconnect if there's a network error going on.
The manager *should* keep reconnecting unless the token is invalid

* src: Enhance onClose handler for shards in the manager
- If the close code is between 1000 and 2000 (inclusive), you cannot resume
I tested this locally
- If there's a session ID still present, immediately try to resume
Faster resumes :papaBless:
Otherwise, the invalid session event will trigger and it'll handle accordingly

I swear if I see a SINGULAR Silent DC I'm yeeting

* src: Fix error check

* src: Make sure message exists on the error

* src: Used the wrong property for the shardQueue

* src: Make the hello timeout be made by the client
god help

* docs: Correct docs for WSEvents

* misc: Remove old events from the Events constant

* src: Throw the HTTP error if we don't get a 401

* typings: Can't forget about them

* src: Implement some more fail safes just in case
Seriously, better safe than sorry! Gotta failproof it completely
2019-04-01 09:43:45 +02:00
Ryan Munro
4b6e8fcab5 typings(Collection): add missing thisArg to partition (#3167) 2019-04-01 09:36:03 +02:00
Ryan Munro
831f988fe2 typings(Collection): add typings for partition (#3166) 2019-04-01 09:35:17 +02:00
izexi
5cd6d8d380 feat(Guild): add fetchBan and withReasons to fetchBans (#3170)
* add Guild#fetchBan() & backport BanInfo

* and the typings

* requested changes

* typings overloads

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>

* nullable reason typings

Co-Authored-By: izexi <43889168+izexi@users.noreply.github.com>
2019-04-01 09:07:52 +02:00
Schuyler Cebulskie
04fa56d0c0 Improve structure extension errors 2019-03-24 16:45:34 -04:00
Amish Shah
b74a4356dd fix lint errors 2019-03-23 12:54:22 +00:00
Amish Shah
6adb0a6609 voice: add ability to delete broadcasts 2019-03-23 12:52:18 +00:00
Amish Shah
9a092b6e57 voice: rename createVoiceBroadcast to createBroadcast 2019-03-23 12:37:55 +00:00
Amish Shah
c8225631c9 voice: move broadcasts to client.voice 2019-03-23 12:36:53 +00:00
Amish Shah
3df56540e2 voice: add documentation to VoiceBroadcast 2019-03-23 12:22:55 +00:00
Amish Shah
745e18b823 fix #3150: can now create dispatcher with 0 volume 2019-03-22 12:43:51 +00:00
izexi
9b2bf03ff6 feat(MessageStore): add cache parameter to fetchPinned() (#3154)
* add cache param to MessageStore#fetchPinned()

* typings for cache param

* set cache to true by default
2019-03-19 20:35:58 +01:00
izexi
2341d13615 fix: messageReactionRemove not emitting for partial messages (#3125) 2019-03-19 20:32:11 +01:00
SpaceEEC
e62833b5e1 docs: mark getters as @ readonly 2019-03-19 19:59:45 +01:00
Ryan Munro
df1889ab49 cleanup(Guild): removed fetchAuditLogs' "after" option (#3142)
* Removed code and documentation for Guild.fetchAuditLogs "after" option

* Also removed the option from typings
2019-03-12 19:14:32 +01:00
bdistin
1673b6f8f5 fix(APIMessage): edit shouldn't remove content (#3129)
* edit shouldn't remove content

If undefined is passed to the api, content isn't removed in such a case where you are only editing the embed.

* fix a related doc string

* update typings

* requested changes
2019-03-08 17:57:59 +01:00
Souji
be2f78851f docs/typings: RateLimitInfo#limit instead of requestLimit (#3132)
* fix doc for ratelimit data, fixes #3131

* adapt typings

* typings: unindent #region comments
2019-03-07 16:34:23 +01:00
Antonio Román
132788937a src: add missing events in constants (#3124)
* src: Add missing events in constants

* fix: Restore 'use strict';
2019-03-05 17:18:11 +01:00
Kamran Mackey
1207c243d1 typings(Guild): add missing defaultRole property (#3126)
* [typings] Fix missing defaultRole property under Guild.

Signed-off-by: Kamran Mackey <kamranm1200@gmail.com>

* [typings] Added missing readonly identifier.

Signed-off-by: Kamran Mackey <kamranm1200@gmail.com>
2019-03-04 20:32:15 +01:00
SpaceEEC
579283dfe9 fix(Role): proper undefined check for data.permission when editing 2019-03-02 21:58:40 +01:00
Amish Shah
6e761eb030 fix typo 2019-02-26 13:10:39 +00:00
SpaceEEC
32ad56a562 docs(Guild): update createChannel examples to not use deprecated overload 2019-02-25 11:09:46 +01:00
Cam Cope
f61c044b26 Mark peer dependencies as optional (#3066) 2019-02-24 08:43:42 +00:00
bdistin
fe5563e158 refactor(User): avoid invoking dmChannel getter more than once per method (#3108)
also refactors to async methods
2019-02-24 09:37:10 +01:00
Linn Dahlgren
7006f00ae4 feat(MessageEmbed): add missing proxyURL property to video (#3109)
* Added missing property to MessageEmbed.video

* Updated typings for MessageEmbed.video
2019-02-24 09:27:57 +01:00
Kyra
bc0a761e22 typings: Convert types to interfaces where applicable (#3068) 2019-02-23 22:14:09 -06:00
Linn Dahlgren
4d3f76656a docs(MessageEmbed): add missing type value (#3106) 2019-02-23 10:05:04 +01:00
Amish Shah
73be952406 use official release of prism 2019-02-21 11:56:46 +00:00
Amish Shah
efbbfbcec6 fix #3102 2019-02-20 19:15:33 +00:00
Amish Shah
6aa792f9ab voice: cleanup internals whether end() or destroy() is called 2019-02-19 13:16:48 +00:00
Amish Shah
4009986bc8 voice: destroy opus 2019-02-17 21:48:47 +00:00
Amish Shah
0564c5c777 voice: update prism 2019-02-14 16:57:26 +00:00
SpaceEEC
4289b18ab2 docs(GuildMember): add missing @name to document user property
Fixes #3090
2019-02-14 11:19:05 +01:00
Amish Shah
5c3f5d7048 Partials (#3070)
* Remove GroupDMChannels

they sparked no joy

* Start partials for message deletion

* MessageUpdate partials

* Add partials as an opt-in client option

* Add fetch() to Message

* Message.author should never be undefined

* Fix channels being the wrong type

* Allow fetching channels

* Refactor and add reaction add partials

* Reaction remove partials

* Check for emoji first

* fix message fetching

janky

* User partials in audit logs

* refactor overwrite code

* guild member partials

* partials as a whitelist

* document GuildMember#fetch

* fix: check whether a structure is a partial, not whether cache is true

* typings: Updated for latest commit (#3075)

* partials: fix messageUpdate behaviour (now "old" message can be partial)

* partials: add warnings and docs

* partials: add partials to index.yml

* partials: tighten "partial" definitions

* partials: fix embed-only messages counting as partials
2019-02-13 17:39:39 +00:00
Amish Shah
8910fed729 voice: debug UDP (#3044) 2019-02-12 16:29:11 +00:00
SpaceEEC
45a17e7ebd fix(Emoji): reject explicit error when MANAGE_EMOJI permissions are missing (#3063) 2019-02-12 10:16:23 +01:00
SpaceEEC
49e8bd9edd feat(RichEmbed): add timestamp support for setTimestamp (#3061) 2019-02-12 10:15:37 +01:00
SpaceEEC
1618829cc6 fix(Util): splitMessage throws an error if a chunk is too large (#3060) 2019-02-12 10:14:49 +01:00
SpaceEEC
a0ff72b556 fix(GuildMember): add explicit channel resolve error to member edit (#3059) 2019-02-12 10:13:37 +01:00
SpaceEEC
7bc2e231cf feat(Guild): add position to createChannel's implementation (#3058) 2019-02-12 10:12:25 +01:00
SpaceEEC
890b1be714 feat(RichEmbed): add length getter (#3057) 2019-02-12 10:11:44 +01:00
SpaceEEC
a2a0c05102 feat(Presence): add clientStatus (#3056) 2019-02-12 10:10:33 +01:00
Kyra
5c19ad7252 cleanup: Error messages cleanup (#3079)
Removed keys that return zero occurrences in the library's source code
2019-02-12 08:13:15 +00:00
Kyra
0c7a618f10 cleanup: remove unused members of classes (#3078)
* cleanup: Remove unused members of classes

* typings: Remove hit from Message
2019-02-11 20:33:13 +01:00
Amish Shah
c362ba0dd5 voice: more debug 2019-02-11 18:37:33 +00:00
Amish Shah
fe51b4e89b voice: more debug information, correctly listen to vws 2019-02-11 18:28:37 +00:00
Amish Shah
375706beac voice: replace self.xyz events 2019-02-11 18:03:35 +00:00
Amish Shah
810b5a5f71 voice: more debug info 2019-02-11 17:57:56 +00:00
Amish Shah
283fc54ce4 More debug information 2019-02-11 17:39:19 +00:00
Amish Shah
a705edfd0d voice: more debug information 2019-02-11 17:22:17 +00:00
Kyra
ab55acffdb webpack: Fix module warning when building (#3076)
Warning:
```
WARNING in ./src/client/Client.js
Module not found: Error: Can't resolve 'worker_threads' in 'D:\Repositories\discordjs\discord.js\src\client'
 @ ./src/client/Client.js
 @ ./src/index.js
```
2019-02-11 16:29:20 +00:00
Kyra
0c5b9c6870 chore(deps): Updated all required, peer, and development dependencies (#3073)
* chore(deps): Updated all required, peer, and development dependencies

And engines.node to require 10

* chore(peerDeps): Updated uws to 11.149.1

Clarified my doubts with iCrawl
2019-02-11 07:41:37 +00:00
Amish Shah
aab3523fb5 voice: more debug information
#3074, #2979, #3044
2019-02-10 20:18:08 +00:00
Vlad Frangu
793341dbb4 fix: Sharding issues, silent disconnects and code cleanup (#2976)
* fix: Sharding bugs, silent disconnects and cleanup code

* typings

* fix: Destroy connecting with close code different from 1000
Per `If a client does not receive a heartbeat ack between its attempts at sending heartbeats, it should immediately terminate the connection with a non-1000 close code, reconnect, and attempt to resume.`

* misc: Wait x ms before reconnecting
Per https://discordapp.com/developers/docs/topics/gateway#resuming

* docs

* nit: docs

* misc: Prevent multiple calls to WebSocketManager#destroy

* fix: Implement destroying if you reset the token

* misc: Clear the WS packet queue on WebSocketShard#destroy
You can't send those packets anywhere anymore, so no point in keeping them

* fix: Handle session limits when reconnecting a full shard, cleanup

* misc: No need to create a new shard instance

* fix: closeSequence being null, thus emitting null on Client#resumed

* misc: Remove GUILD_SYNC Gateway handler and add missing dot to string

* misc: Close WS with code 4000 if we didn't get a heartbeat in time

As said in the Discord API server

* fix: Handle ready emitting in onPacket
Doesn't allow broken packets

* misc: Close the connection if Discord asks for a reconnect
Prevents double triggers

* testing: Prevent multiple reconnect attempts on a shard

Should fix some issues some people have had.

* fix: Prevent multiple reconnect calls on the shard, re-use conn to identify, remove reconnect function
Note: Closing the WS with 1000 makes the session invalid

* misc: Forgot to remove 2 unneeded setters

* docs: Wrong param docstring for WebSocketShard#destroy

* misc: Set status to reconnecting after destroying

* misc: Close connection with code 1000 on session invalidated
Allows us to cleanup the shard and do a full reconnect
Also remove identify wait delay, not used anywhere

* fix: Fix zlib crash on node
And with that, the PR is done!

* misc: Implement a reconnect queue
And that is all there was to be done in this PR.
Shards now queue up for a reconnect

* nit: Debug the queue after destroying

* docs: Make the invalidated event clearer

* lint: I'm good at my job

* docs

* docs: Make description for isReconnectingShards accurate
*can I stop finding issues, this PR is meant to be done*

* misc: Remove shard from bind params

* misc: Code re-ordering and cleanup
Resumes do not need to be queued up, as they do not count to the identify limit, and after some testing, they don't have the 5 second delay required, like in identify

* fix: Issues with token regeneration and shards not properly handling them
We close the ws connection with code 1000 if we get an invalid session payload,
that way we can queue the reconnects and handle any issues

* misc: Remove useless delays on session invalidated
They get handled by the rest of the code already

* lint

* misc: reset the sequence on Shard#destroy
This especially is a problem if you need to re-identify, as the sequence doesn't get set to the current one,
causing the sequence to be wrong

* fix: GitHub rebase and minor tweak
* Implement a 15 second timeout if shards don't connect till then
Should prevent shards that never reconnect

* revert: Make WebSocketShard#send and WebSocketManager#broadcast public

* typings: Set type to void instead of undefined

* docs: Requested Changes
2019-02-10 16:28:03 +00:00
SpaceEEC
7324a993ed fix: ensure VIEW_CHANNEL permissions before trying to join (#3046)
* fix: ensure VIEW_CHANNEL permissions before joining

* nit(GuildChannel): remove the redundant truthy check
2019-02-10 15:21:59 +00:00
Atlas
ff95e587cb Better wording (#3032) 2019-02-09 23:53:47 +00:00
SpaceEEC
5272cec6c8 feat(Util): add WHITE as color resolvable (#3062) 2019-02-09 23:52:38 +00:00
Kyra
d057a5040c ci: Test in Node.js 10 and 11, deploy with Node.js 10 (#3069) 2019-02-09 23:51:23 +00:00
Kyra
9449f8df8f cleanup(GuildMember{RoleStore}): Rewrite to async/await (#3072)
- Fixed a bug where `GuildMemberRoleStore#{add,remove}` would create a rejected promise inside a promise, instead of rejecting the first one.
- Fixed a bug where `GuildMember#edit` with a specified unknown channel would throw synchronously, instead of rejecting asynchronously.
2019-02-09 17:20:10 +00:00
Kyra
c432591113 feat(RoleStore, ChannelStore): fetch() method (#3071)
* feat({Role,Channel}Store): fetch method

* docs: Add usage examples to the new methods

* misc: Add note of why we are fetching all roles even for a single one
2019-02-09 15:07:31 +00:00
Kyra
359ddaf1df feat(Constants): add error code 50020 (#2953)
* feat(Constants): Add error code 50020

Which is throw when using the vanity-url endpoint: https://github.com/discordapp/discord-api-docs/pull/748/

* docs: Document the new code
2019-02-06 22:09:00 +01:00
Lucas Kellar
8b602ebed4 typings(SnowflakeUtil): add optional "timestamp" parameter to generate (#2998) 2019-02-06 19:14:52 +01:00
Kyra
ae7269088b typings(ShardClientUtil): fix id property type (#3054)
Ref: d98d464d74/src/sharding/ShardClientUtil.js (L50)
2019-02-06 18:15:05 +01:00
Amish Shah
f826c9c75e voice: workaround for receiving audio
(#2929 and discordapp/discord-api-docs#808)
2019-02-05 10:26:16 +00:00
Kyra
d98d464d74 typings(GuildCreateChannelOptions): added missing properties (#3052)
* typings(GuildCreateChannelOptions): Added missing properties

* typings: Added `GuildChannelCloneOptions`
2019-02-04 17:57:13 +01:00
Kyra
dd8ba00af4 misc(index): export HTTPError class (#3051) 2019-02-04 16:44:21 +01:00
Isabella
75e264da57 feat: Presence#clientStatus (#2997)
* feat: Presence#clientStatus

* fix Presence#equals check

* fix typings

* vlad changes

* presence consistency docs

* fix docs

* fix big docs fail
2019-02-02 20:29:47 +01:00
Rattmann (fallen)
1db78994dd feat: MessageEmbed#length (#3003)
* add MessageEmbed#length

* update typings (+MessageEmbed#length)

* eslint: L181 (max line length), L183 (missing semi)

* eslint: L181 (trailing space)
2019-02-02 20:29:10 +01:00
SpaceEEC
db3ae0159b docs(Structures): note about extending prior to instantiating client (#2884) 2019-02-02 20:28:24 +01:00
Marcel Menzel
f2ed93c08a fix(WebSocketShard): report correct resumed event count (#3019)
This PR attempts to fix the reported resumed event count in the debug output (where it is always displayed only as 1 event replayed) and in the emitted `resumed` event, where it passed the current sequence instead of passing the actual replayed event count (which was an utopic high number for smaller bots on resume).
2019-02-02 11:28:45 +01:00
Kyra
2dcdc798ac typings: add missing ImageSize numbers (#3045)
To match the JS typedef: https://discord.js.org/#/docs/main/master/typedef/ImageURLOptions
2019-02-02 10:42:13 +01:00
Anthony Collier
3dff5058f0 docs(Examples): fix usage of removed overload of Collection#find (#3027) 2019-01-21 17:22:24 +01:00
SpaceEEC
73aaab5106 fix(Guild): ignore voice states referencing an invalid channel
This was causing an uncaught exception on startup (or whenever receiving such a payload) which is crashing the process.
2019-01-17 11:34:10 +01:00
izexi
3b7b282b69 docs(Client): add missing example tag and closing parenthesis (#3024) 2019-01-17 09:58:04 +01:00
Darqam
5ed2a95856 docs(Client): add missing parenthesis in fetchInvite example (#3023)
This is already fixed in master, resolves #3022
2019-01-16 19:17:19 +01:00
Isabella
8230255c68 fix(ShardClientUtil#id): erroneously reporting as an array 2019-01-15 01:45:29 -06:00
SpaceEEC
28db527370 docs(Guild): use 'updated' variable in example for setRegion 2019-01-10 16:54:02 +01:00
SpaceEEC
46fd7b093c docs(Guild): use AuditLogAction for fetchAuditLogs' type option 2019-01-10 13:05:33 +01:00
SpaceEEC
17ca83663f typings(TextBasedChannel): fix create(Message)Collector's options type 2019-01-06 17:51:27 +01:00
SpaceEEC
9d83516918 typings(Guild): fix typos in method names
Fixes #3009
2018-12-31 18:21:22 +01:00
SpaceEEC
89a9b93cdc docs(Webhook): add mising '@name' to Webhook#token's docstring 2018-12-30 12:56:33 +01:00
SpaceEEC
840d22f892 docs(Webhook): add mising '@name' to Webhook#token's docstring 2018-12-30 12:52:33 +01:00
Amish Shah
0bde9ca2c5 voice: set seek parameter before input (#2993) 2018-12-27 18:05:54 +00:00
Kyra
8a76cc5c72 typings(TextBasedChannel): add Snowflake[] overload to bulkDelete (#3001)
* typings: Add `string[]` overload to bulkDelete

* misc: Requested changes
2018-12-25 22:00:46 +01:00
Drahcirius
7186c91063 fix(TextBasedChannel): added missing lastMessage functionality in textchannels (#2999) 2018-12-23 22:16:50 -06:00
Lucas Kellar
8286d1a0fc typings(SnowflakeUtil): add optional "timestamp" parameter to generate (#2998) 2018-12-23 23:16:28 +01:00
SpaceEEC
21ec03140f feat(GuildChannelStore): add support for create to accept a position (#2965) 2018-12-22 08:50:33 +01:00
Will Nelson
5cbdf38028 fix(WebSocketShard): add websocket send error handling (#2981)
* websocket send error handling

* fix: emit only when error is present

* refactor: use an if instead
2018-12-22 08:49:56 +01:00
izexi
2aa8e1d9c1 docs:(TextChannel): add documentation for messages and lastMessage (#2986)
* [docs] add missing docs for <TextChannel>.messages

* add missing doc for <TextChannel>.lastMessage
2018-12-22 08:25:24 +01:00
August
b5d5c699e6 fix: guildBanRemove event name (#2983)
- "Events.GUILD_BAN_REMOVEGUILD_BAN_REMOVE" -> "Events.GUILD_BAN_REMOVE"
2018-12-09 09:30:46 +01:00
Gus Caplan
42505b78c1 chore: add strict mode (#2974) 2018-12-03 15:19:10 -06:00
SpaceEEC
ecaec29380 fix(Util): throw an explicit error if a chunk exceeds the max length (#2936)
* fix(Util): throw an explicit error if a chunk exceeds the max length

* refactor(Util): consolidate both errors in splitMessage into one

* revert(Messages): do not unnecessarily change the error code

* revert(Messages): do not remove the word 'the'
2018-11-27 21:42:28 +01:00
Darqam
23a16c3a73 fix(GuildChannel): add explicit channel resolve error to member edit (#2958)
* Add explicit error to setting invalid voice channel

* restrict to guild

Co-Authored-By: Darqam <anhim2@gmail.com>

* add a more explicit error and channel type check

* bad tab
2018-11-27 21:41:34 +01:00
SpaceEEC
fd21bbb7bf docs: move event docstrings to the emitting line of code 2018-11-27 21:28:36 +01:00
Skillz4Killz
1d1b3f25e1 docs: add documentation for Client#channelCreate (#2967) 2018-11-27 21:12:25 +01:00
SpaceEEC
351f0a32bf typings(RichEmbed): add MessageEmbed as valid data in constructor
See #2970
2018-11-26 18:08:31 +01:00
SpaceEEC
a8b47a7a6c feat(GuildChannelStore): add support for create to accept a position 2018-11-23 19:46:11 +01:00
Frangu Vlad
9085138f0d fix: Sharding Issues & Cleanup (#2952)
* fix: Sharding causing constant heartbeat / identify spam

* misc: Remove wait param in connect

* misc: Wait 2.5 seconds before sending identify again if session is resumable

* misc: Remove useless destroy call

* nit: Capitalization

* fix: Identify on HELLO not connectionOpen

* misc: Add different intervals for identify after invalid session
- 2500 if we couldn't resume in time
- 5000 if we didn't have a session ID (per the docs on identify, that a client can only connect every 5 seconds)
- Otherwise, just identify again

* misc: Only clear heartbeat if shard is fully dead

Reconnect clears it otherwise

* fix: Accessing .length on a Collection
2018-11-21 13:42:37 -06:00
Crawl
377ecd73ea docs(GuildChannel): fix doc string for clone method 2018-11-20 16:42:27 +01:00
SpaceEEC
691aaef07e backport(Guild): support for rateLimitPerUser when creating a channel
PR: #2878
Commit: 8ec3b5134d
2018-11-17 17:24:48 +01:00
SpaceEEC
6aa7792097 docs(GuildChannel): add rateLimitPerUser to ChannelData typdef 2018-11-17 17:19:04 +01:00
SpaceEEC
d92ee2ff99 feat(GuildChannel): allow to set all options when cloning (#2937) 2018-11-17 15:43:04 +01:00
Charalampos Fanoulis
81ff5075e4 chore: remove user account checkbox from bug report template 2018-11-17 15:41:12 +01:00
Yukine
e793338d74 fix: ShardClientUtil#count and ShardClientUtil#id typedef (#2956) 2018-11-16 22:46:02 -06:00
Kyra
54aff3191e feat(Constants): add error code 50020 (#2953)
* feat(Constants): Add error code 50020

Which is throw when using the vanity-url endpoint: https://github.com/discordapp/discord-api-docs/pull/748/

* docs: Document the new code
2018-11-16 16:55:15 +01:00
Amish Shah
2d68e837e5 voice: fix receiver null on immediate voiceStateUpdate 2018-11-15 21:38:02 +00:00
Lewdcario
3418b5a1a2 docs: restore Client#error docs that went missing 2018-11-06 14:59:02 -06:00
Souji
980d71f307 fix:(GuilChannel): clone method not taking overwrites into account (#2932) 2018-11-06 20:01:48 +01:00
Lewdcario
6b886b0aba typings: add Guild#shard and Guild#shardID 2018-11-06 11:23:17 -06:00
Lewdcario
08002d0576 fix: Client#userUpdate receiving wrong packet 2018-11-05 18:24:50 -06:00
Lewdcario
b59c75e402 docs: add missing docstring for Client#guildDelete 2018-11-05 13:29:07 -06:00
Souji
905f1c3262 docs: add missing docstring for Client#userUpdate (#2930)
* docs: add missing docstring for Client#userUpdate

* docs: indentn't

* docs: indentn't 2
2018-11-05 17:46:47 +01:00
Lewdcario
7796cb5d05 fix: Client#raw emitting twice 2018-11-04 23:26:40 -06:00
Lewdcario
be0d1cd663 fix: Client#shards not being set properly 2018-11-04 23:25:54 -06:00
Amish Shah
b3f459091f Fix #2928 (member not being removed from voice channel after leaving guild) 2018-11-04 12:26:06 +00:00
Isabella
f3cad81f53 feat: Internal sharding (#2902)
* internal sharding

* ready event

* the square deal

* the new deal

* the second new deal

* add actual documentation

* the new freedom

* the great society

* federal intervention

* some of requested changes

* i ran out of things to call these

* destroy this

* fix: Client#uptime went missing

* fix(Client): destroy the client on login failure

This may happen duo invalid sharding config / invalid token / user requested destroy

* fix(Client): reject login promise when the client is destroyed before ready

* fix(WebSocketManager): remove redundancy in destroy method (#2491)

* typo(ErrorMessages): duo -> duo to

* typo(ErrorMessages): duo -> due

* fix: docs and options

* docs(WebSocketManager): WebSockethard -> WebSocketShard (#2502)

* fix(ClientUser): lazily load to account for extended user structure (#2501)

* docs(WebSocketShard): document class to make it visible in documentation (#2504)

* fix: WebSocketShard#reconnect

* fix: presenceUpdate & userUpdate
* presenceUpdate wasn't really being handled at all
* userUpdate handled incorrectly because as of v7 in the Discord API, it comes inside presenceUpdate

* re-add raw event

* member is now part of message create payload

* feat: Add functionality to support multiple servers with different shards (#2395)

* Added functionallity to spawn multiple sharding managers due to adding start and end shards

* Small fixes and limiting shard amount to max recommended

* Forgot a check in spawn()

* Fixed indentation

* Removed optiosn object documentation for totalShards

* More fixes and a check that the startShard + amount doesnt go over the recommended shard amount

* fix getting max recommended

* Removed async from constructor (my fault)

* Changed start and end shard to a shardList or "auto" + fixed some brainfarts with isNaN

* Changed the loop and totalShard count calculation

* shards are actually 0 based

* Fixed a problem with the gateway and handled some range errors and type errors

* Changed Number.isNan to isNaN and changed a few Integer checks to use Number.isInteger

* Added check if shardList contains smth greater than totalShards; made spawn use totalShards again; shardList will be ignored and rebuild if totalShards is 'auto'; fixed docs

* ShardingManager#spawn now uses a for..of loop; fixed the if statement inside the new for..of loop to still work as intended; made the totalShards be set to a new amount if smth manual is put into ShardingManager#spawn just like before; Fixed some spelling

* internal sharding

* ready event

* the square deal

* the new deal

* the second new deal

* add actual documentation

* the new freedom

* the great society

* federal intervention

* some of requested changes

* i ran out of things to call these

* destroy this

* fix: Client#uptime went missing

* fix(Client): destroy the client on login failure

This may happen duo invalid sharding config / invalid token / user requested destroy

* fix(Client): reject login promise when the client is destroyed before ready

* fix(WebSocketManager): remove redundancy in destroy method (#2491)

* typo(ErrorMessages): duo -> duo to

* typo(ErrorMessages): duo -> due

* fix: docs and options

* docs(WebSocketManager): WebSockethard -> WebSocketShard (#2502)

* fix(ClientUser): lazily load to account for extended user structure (#2501)

* docs(WebSocketShard): document class to make it visible in documentation (#2504)

* fix: WebSocketShard#reconnect

* fix: presenceUpdate & userUpdate
* presenceUpdate wasn't really being handled at all
* userUpdate handled incorrectly because as of v7 in the Discord API, it comes inside presenceUpdate

* Internal Sharding adaptation

Adapted to internal sharding
Fixed a bug where non ready invalidated sessions wouldnt respawn

* Fixed shardCount not retrieving

* Fixing style

removed unnecessary parenthesis

* Fixing and rebasing

lets hope i didnt dun hecklered it

* Fixing my own retardation

* Thanks git rebase

* fix: assigning member in message create payload

* fix: resumes

* fix: IS wont give up reconnecting now

* docs: add missing docs mostly

* fix: found lost methods

* fix: WebSocketManager#broadcast check if shard exists

* fix: ShardClientUtil#id returning undefined

* feat: handle new session rate limits (#2796)

* feat: handle new session rate limits

* i have no idea what i was doing last night

* fix if statement weirdness

* fix: re-add presence parsing from ClientOptions (#2893)

* resolve conflicts

* typings: missing typings

* re-add missing linter rule

* fix: replacing ClientUser wrongly

* address unecessary performance waste

* docs: missing disconnect event

* fix(typings): Fix 2 issues with typings (#2909)

* (Typings) Update typings to reflect current ClientOptions

* fix(Typings) fixes a bug with Websockets and DOM Types

* fix travis

* feat: allow setting presence per shard

* add WebSocketManager#shardX events

* adjust typings, docs and performance issues

* readjust shard events, now provide shardId parameter instead

* fix: ready event should check shardCount, not actualShardCount

* fix: re-add replayed parameter of Client#resume

* fix(Sharding): fixes several things in Internal Sharding (#2914)

* fix(Sharding) fixes several things in Internal Sharding

* add default value for shards property

* better implement checking for shards array

* fix travis & some casing

* split shard count into 2 words

* update to latest Internal Sharding, fix requested changes

* make sure totalShardCount is a number

* fix comment

* fix small typo

* dynamically set totalShardCount if either shards or shardCount is provided

* consistency: rename shardID to shardId

* remove Client#shardIds

* fix: typo in GuildIntegrationsUpdate handler

* fix: incorrect packet data being passed in some events (#2919)

* fix: edgecase of ShardingManager and totalShardCount (#2918)

* fix: Client#userUpdate being passed wrong parameter
and fix a potential edgecase of returning null in ClientUser#edit from this event

* fix consistency and typings issues

* consistency: shardId instances renamed to shardID

* typings: fix typings regarding WebSocket

* style(.eslintrc): remove additional whitespace

* fix(Client): remove ondisconnect handler on timeout

* docs(BaseClient): fix typo of Immediate

* nitpick: typings, private fields and methods

* typo: improve grammar a bit

* fix: error assigning client in WebSocketManager

* typo: actually spell milliseconds properly
2018-11-03 13:21:23 -05:00
Schuyler Cebulskie
18f065867c Fix #2924 with a bandage (Node typings not updated) 2018-11-03 13:09:56 -04:00
Schuyler Cebulskie
ab3a439198 Add worker-based sharding to the ShardingManager (#2908)
* Add worker-based sharding mode to ShardingManager

* Fix ClientShardUtil mode

* Fix worker not being cleared on shard death

* Update docs and typings

* Clean up Client sharding logic a bit

* Add info about requirements for worker mode
2018-10-29 15:02:36 -04:00
Schuyler Cebulskie
b759fc415e Slightly simplify logic in APIMessage.transformOptions 2018-10-27 15:28:05 -04:00
SpaceEEC
01476de582 fix(VoiceConnection): compare new speaking to old to avoid TypeError 2018-10-20 12:12:21 +02:00
sillyfrog
2ba00038d1 fix(VoiceConnection): use Speaking#has to fire _stoppedSpeaking (#2896)
* Use match on speaking bitmask to fire _stoppedSpeaking

* Use constants and correct matching

* Correctly do a not check
2018-10-19 18:15:01 +02:00
Lewdcario
e189c1b728 fix: revert #2744
see #2848, fixes issues with stack not displaying correctly
2018-10-15 02:08:49 -05:00
Lewdcario
16076124b2 fix(Client#voiceStateUpdate): newState is guaranteed 2018-10-14 13:58:34 -05:00
Isabella
183ba25faf fix: emit voiceStateUpdate on guildMemberRemove (#2892)
* fix: emit voiceStateUpdate on guildMemberRemove

* apparently i am blind

* typings
2018-10-14 12:44:14 -05:00
Isabella
950abd4ac3 fix: revert #2768 (#2848)
* fix: revert #2768

* fix merge
2018-10-14 11:44:02 -05:00
Lewdcario
9cf50d05f2 fix(typings): ReactionUserStore#fetch returns a Collection
fixes #2895
2018-10-13 20:09:19 -05:00
SpaceEEC
73b9b0e62b fix(Shard): use DISCORD_TOKEN instead of CLIENT_TOKEN, see #2843 2018-10-13 15:20:56 +02:00
Amish Shah
2e7094f9ea voice: fix disconnect without receiver edge case 2018-10-11 23:02:59 +01:00
SpaceEEC
4491b7b42a typings(MessageEmbed): add spliceField and static checkField methods 2018-10-10 11:30:26 +02:00
Souji
fd25d19c9c docs(ClientUser): fix example for setActivity method (#2880) 2018-10-10 10:30:23 +02:00
Souji
78c4be52c6 docs(Collection): clarify example for tap method (#2881)
* docs: clarify example for Collection#tap

* docs: wording improvement
2018-10-10 10:29:53 +02:00
SpaceEEC
6e5f088e44 refactor: consistently use permissionOverwrites over overwrites (#2886) 2018-10-10 10:25:00 +02:00
SpaceEEC
7ea88adeca backport(Guild): support for createChannel with options object (#2888) 2018-10-10 10:05:32 +02:00
SpaceEEC
71c04a303a feat(Emoji): move createdAt and createdTimestamp getters from GuildEmoji (#2872) 2018-10-10 10:01:23 +02:00
SpaceEEC
ea3e575546 backport(TextBasedChannel): add lastPinTimestamp and lastPinAt (#2870)
And clarify Client#channelPinsUpdate's 'time' parameter.
2018-10-10 10:01:04 +02:00
Will Nelson
1ee417cd65 featt(ClientUser): allow options as first parameter to setActivity (#2890) 2018-10-10 09:59:16 +02:00
Dim
8ec3b5134d feat(GuildChannelStore): support for create with rateLimitPerUser (#2878)
* change GuildChannelStore#create

* document rateLimitPerUser

* update typings
2018-10-10 09:58:31 +02:00
bdistin
8feb874586 feat(MessageEmbed): add spliceField method (#2857)
* Add spliceField and refactor to prevent code dupe

* String() was for a falsy check, fixed

* requested: remove embed field count checks
2018-10-10 09:57:56 +02:00
Isabella
1fe36087d4 feat(MessageEmbed): allow setTimestamp to take a timestamp (#2875)
* feat: allow MessageEmbed#setTimestamp to take a timestamp

* fix the dumb i did
2018-10-10 09:57:13 +02:00
SpaceEEC
27d2ce7baf typings(Collection): each return Collection<K, V>, not void 2018-10-05 11:37:49 +02:00
Amish Shah
00a62a93e4 voice: catch errors before connection is ready 2018-10-04 20:57:52 +01:00
SpaceEEC
fcf4745a43 typings: fix lint script and linter errors 2018-10-04 19:29:12 +02:00
SpaceEEC
b92f8d9c06 docs(Game): document possible values for type property
See #2865
2018-10-04 13:31:26 +02:00
SpaceEEC
6b810b2331 fix(ClientPresence): use possibly extended constructor from structures 2018-10-04 12:36:25 +02:00
SpaceEEC
1428967238 docs(Integration): document Integration class 2018-10-04 11:01:21 +02:00
SpaceEEC
c6201ee41b backport(Guild): add fetchVanityCode (#2871) 2018-10-03 17:31:20 -05:00
Isabella
1e85887229 backport: rateLimitPerUser (#2874) 2018-10-03 17:21:26 -05:00
SpaceEEC
e0f522a745 backport(ClientOptions): add retryLimit (#2869) 2018-10-03 17:20:53 -05:00
Daniel
62e7e26310 Add white to colours (#2853)
* add white to colorresolvable typedef

* add colour white
2018-10-01 14:02:50 +02:00
bdistin
96a0655609 refactor(WebhookClient): make token property non-enumerable (#2861)
* make WebhookClient#token non-enumerable

parity with Client to add the barest protection against accidental exposure

* requested change
2018-10-01 12:43:08 +02:00
bdistin
d8c97be142 docs: fix typos (#2868) 2018-10-01 12:38:36 +02:00
SpaceEEC
21999fa4a0 fix(typings): fix compilation with 'strict' enabled (#2845) 2018-09-30 11:30:07 +02:00
Kyra
d4c0bb2a0d feat(TextChannel): RateLimitPerUser (#2811)
* feat: Add TextChannel#rateLimitPerUser
Rename parameter in TextChannel#setRateLimitPerUser
feat: Add `rateLimitPerUser` param to ChannelData
fix: eslint

* docs: Updated typings

* fix: Requested changes

* fix: rateLimitPerUser being undefined when 0

When `rate_limit_per_user` is 0, the gateway does not send it (but REST does). When this is set to a non-zero number, this property starts to exist. Otherwise this will be `0`. Adding `|| 0` should do the trick changing `undefined` to `0`.

* fix: eslint
2018-09-29 16:02:49 +02:00
Kyra
60ad9053a3 typings: add HTTPError class definition (#2852)
Class was introduced with #2694 

* typings: Add HTTPError class definition

* typings: Sort HTTPError's members by name
2018-09-23 22:07:19 +02:00
Shayne Hartford
32b405a5be Change default token (#2843)
* Change default token

Default `token` to `process.env.CLIENT_TOKEN` like client does.

* 2/2

* 1/2
2018-09-23 21:36:28 +02:00
Andrew Lehman
3298ea1869 docs: correct default value for SplitOptions.maxLength in Util#splitMessage (#2847) 2018-09-23 21:35:56 +02:00
SpaceEEC
0ab69c5ad4 fix(Webhook): APIMessage require should be a const 2018-09-23 17:04:22 +02:00
SpaceEEC
c0a9b08e73 fix(Webhook): APIMessage is not circular, fixes WebhookClients 2018-09-23 17:02:35 +02:00
SpaceEEC
3f44320bbe docs(MessageAttachment): redocument name property 2018-09-22 11:45:03 +02:00
Lewdcario
53420fa4e7 fix: Webhook#send not resolving content 2018-09-21 23:02:31 -05:00
bdistin
3d8207a3db refactor: comprehensive permissionOverwrites refactor (#2818)
* wip: comprehensive permissionOverwrites refactor

* PermissionOverwrites.resolve should Promise.reject()

where a promise is the expected return value

* On second thought, async rewrite to automatically reject on throw

* Fix some docs

* Fix a bug

* fix 2 more bugs

* typings: Updated for latest commit

* typings: Add missing method in GuildChannel

* typings: Add missing `| null` in PermissionOverwriteOption type

* Suggested changes
2018-09-21 12:21:51 +02:00
bdistin
6d184257b3 refactor: remove duplicate send checks (#2790)
* re-direct pr code to master

* fix Webhook send docs

* requested changes

* typings: Updated to latest commit

* requested change

* requested change
2018-09-21 10:59:58 +02:00
Crawl
8a6d029c00 build(dev-deps): update to use terser instead of uglifyjs 2018-09-19 01:20:07 +02:00
SpaceEEC
d2da771e0f docs(Client): fix syntax error in fetchInvite example 2018-09-18 11:04:54 +02:00
SpaceEEC
2cc0a31d5c typings(Message): member property is a readonly getter 2018-09-15 19:49:34 +02:00
SpaceEEC
9de3e098da docs(User): clarify what User#tag represents
Closes #2828
2018-09-10 18:11:09 +02:00
SpaceEEC
1d77d1a9b8 fix(typings): remove UserConnection, fix various constructors
Closes #2825
2018-09-10 13:41:33 +02:00
Ash
9c2924a1b4 docs(ChannelPinsUpdate): clarify time param (#2823) 2018-09-05 14:33:44 +02:00
Ash
e96a60361a feat(TextBasedChannel): add lastPinTimestamp and lastPinAt (#2813)
* add lastPinTimestamp

* typings

* use or instead of ternary
2018-09-03 09:11:52 +02:00
lipgloss
b068abb5de typings: add declaration of Message#url and MessageAttachment#size (#2821)
* add url to message typings

* also its readonly

* message attachment sizing typing
2018-09-03 08:53:20 +02:00
SpaceEEC
75745fe2ba typings(GuildChannel): permissionsFor's return value is nullable 2018-09-02 16:03:03 +02:00
SpaceEEC
ead99a53b7 fix(HTTPError): the path property should actually be the path 2018-09-02 14:57:36 +02:00
SpaceEEC
6b9dd13d43 docs/typings(GuildChannel): permissionsfor returns a nullable readonly Permissions instance 2018-09-02 13:23:39 +02:00
SpaceEEC
b1ce602e79 fix/cleanup(typings): move static properties above methods
Make BitField.FLAGS declaration less strict, allowing enums and typed dicts
2018-09-02 10:42:22 +02:00
Adam Gauthier
038b142db2 fix: emit ReactionCollector#remove when reaction is removed by collected user (#2803) 2018-09-01 05:02:30 +02:00
lipgloss
314161ab70 GuildEmoji.fetchAuthor() error handling (#2788)
* handle when client has insufficient permissions, add typing

* code review
2018-09-01 04:52:50 +02:00
Isabella
be4d6f9dc3 feat: add ClientOptions#retryLimit (#2805)
* feat: add ClientOptions#retryLimit

* hydra needs to learn how to code right

* a default would probably help

* move incrementor & update comment

* clarify docs on Infinity
2018-09-01 04:51:35 +02:00
Ash
3970c5005b cleanup: use null over undefined (#2810) 2018-09-01 04:51:11 +02:00
Crawl
641ee86105 build(peer-deps): use uws fork backport (#2782)
* build(peer-deps): uws backport

* chore: update to 149 for uws
2018-08-30 17:55:31 -05:00
Lewdcario
f75b80d96b docs: add docstring to HTTPError 2018-08-30 16:31:22 -06:00
Souji
da2d4d7230 docs: correct Guild#memberCount (#2812) 2018-08-30 00:15:05 -05:00
Kyra
c63f15c8bc cleanup(Invite): remove outdated props, properly default to null (#2807) 2018-08-29 12:41:53 +02:00
Kyra
cd58599caf fix(Guild#deleteEmoji): reject non emojis / emoji IDs (#2793)
* fix(Guild#deleteEmoji): Performing wrong checks

* fix: requested changes

`a string` -> `an id`

* fix: requested changes

`id` -> `ID`
2018-08-29 08:45:27 +02:00
Adam Gauthier
8821fd40bc cleanup: remove remaining apiRequestMethod docs and typings (#2806) 2018-08-29 08:43:28 +02:00
Kyra
b83fdbfefe docs: Added url to Invite's warning comment (#2804)
And added the [serial comma](https://en.wikipedia.org/wiki/Serial_comma)
2018-08-28 19:12:12 -05:00
Kyra
989c365ef1 fix: Better global ratelimit management (#2801)
* fix: better global ratelimit handling in RequestHandler

fix: Remove useless line

fix: Better global ratelimit management

* refactor: Changed RESTManager#globallyRateLimited to be a getter

* refactor: Remove RESTManager#globallyRateLimited getter

* docs: Updated comments to reflect latest changes
2018-08-28 18:28:21 -05:00
bdistin
f326fe67b1 fix: reactions ratelimits (#2795)
* each reaction doesn't have it's own ratelimit

* fix hard-coded reset for reacting
2018-08-28 18:25:38 -05:00
Kyra
89986ae293 backport: UNKNOWN_WEBHOOK (#2777) 2018-08-28 10:35:34 -05:00
Kyra
091b4fc214 backport: Guild#{fetchEmbed,setEmbed} (#2778)
*  backport: Guild Embeds

* fix: Added missing return

* docs: Updated typings
2018-08-28 10:33:51 -05:00
Kyra
3345c77ce2 backport: GUILD_INTEGRATIONS_UPDATE event (#2794)
* backport: Client#on{guildIntegrationsUpdate,webhookUpdate}

misc: Update Constants.WSEvents and WSEventType

backport: Add guildIntegrationsUpdate event handler

* docs: Updated typings
2018-08-28 10:25:44 -05:00
Ash
1fc84a95d0 fix(GuildChannel#lockPermissions): Properties allow and deny always returning undefined (#2800)
* fix undefined properties

* requested changes
2018-08-26 13:11:00 -05:00
lipgloss
9c2aeb733a fix: private_channels always returns an empty array on ready (#2787) 2018-08-26 13:06:00 -05:00
Kyra
58ba2c7b14 backport: Deprecate allowed/denied as #2765 (#2792) 2018-08-26 13:03:02 -05:00
Lewdcario
2e2c9c4b9a typings: clean up permissionResolvable 2018-08-26 11:55:10 -06:00
Lewdcario
bd14d5d2fa typings: add WEBHOOKS_UPDATE 2018-08-26 11:07:51 -06:00
Kyra
453098117f backport: WEBHOOKS_UPDATE event (#2779) 2018-08-26 11:59:15 -05:00
Lewdcario
93bf430fc7 fix: Guild#addMember incorrectly resolving userID 2018-08-26 09:46:55 -06:00
Amish Shah
6f62d7d816 fix: voice not throwing errors on bad stream input (#2786) 2018-08-25 19:41:07 +01:00
Kyra
469fbe2889 docs(Emoji): fix typo of the word "emoji" (#2791) 2018-08-24 18:31:43 +02:00
Crawl
9b329a457c build(peer-deps): use uws fork (#2781)
* feat: use uws fork

* chore: update to 149 for uws
2018-08-24 16:51:33 +02:00
Souji
cb08a0961a Docs: merge PermissionOverwriteOptions and OverwriteData (#2738)
* Docs: merge PermissionOverwriteOptions and OverwriteData

* fix user-member and replace eslint-disable with linebreaks

* consistency fix

* Fix: remove empty line between jsdocs and method

* Fix: allowed/denied to allow/deny to conform with recent master changes
2018-08-24 16:51:15 +02:00
Kyra
c4df02782e feat: Guild Integrations (#2760)
* feat: Guild Integrations

* feat: Guild#createIntegration

* feat: Add ws event GUILD_INTEGRATIONS_UPDATE

* docs: Add `GUILD_INTEGRATIONS_UPDATE` to WSEventType

* misc: Fixed requested change

* docs: Updated typings

* typings: Sort members by name
2018-08-24 16:03:29 +02:00
Isabella
13f46b924b refactor: clean up rate limit handling (#2694)
* refactor: clean up rate limit handling

* requested changes

* remove request mode option

* fix dupe requests

* hardcode reaction ratelimits

* suggested changes

* fix small thing

* re-add restTimeOffset

* move restTimeOffset a bit

* i swear i know english its my native language ok

* requested changes

* fix: a bit *too* pre-emptive with ratelimits, now less so

* fix: dapi error shoudl reject with path

* fix: make errors in execute catchable

* fix promise return

* rebase is hard
2018-08-24 06:29:44 +02:00
SpaceEEC
82993fbe51 fix(ClientApplication): Message#application is a partial ClientApplication 2018-08-22 19:26:57 +02:00
Kyra
911e289b55 backport: User#dmChannel perf enhancement (#2780) 2018-08-22 11:52:21 +02:00
Kyra
28d4f74b65 misc: update ClientApplication for the current API (#2767)
* misc: Update ClientApplication for the current API

* cleanup: ClientApplication#fetchAssets, removed createAsset

* Major cleanup time

* Merge to kyra's branch

* docs: Updated typings

* fix: re-add ClientApplication#{cover,coverImage()}

* typings(ClientApplication): move coverImage declaration up
2018-08-22 08:10:55 +02:00
Crawl
02f98cd7e6 fix(webpack): properly minifying 2018-08-22 05:05:11 +02:00
Crawl
7684ad3ca6 fix(webpack): properly emitting process deprecation warnings 2018-08-22 04:54:09 +02:00
Isabella
928fb30040 fix: actually fix Readonly typos 2018-08-21 14:25:30 -05:00
Isabella
c59d3299bc fix: typo in Activity#flags 2018-08-21 13:19:45 -05:00
Isabella
552323363b fix: disable getter-return 2018-08-21 12:40:49 -05:00
Isabella
d3e7dbc738 fix: pin & update deps 2018-08-21 11:37:08 -05:00
1Computer1
19c298f5cc refactor: rewrite message creation (#2774)
* Rework createMessage
- MessageAttachment is now structurally similar to FileOptions
- No longer mutates the object passed as options
- Supports more permutations of arguments

* Ignore complexity warning

* Refactor name finding

* Fix typo

* Update typings

* Default name to null for MessageAttachment

* Make Message#reply use transformOptions

* Move transformOptions

* Fix Message#reply

* Fix mutation

* Update tests

* Fix options passing

* Refactor into APIMessage

* Fix webhook send

* Expose APIMessage

* Add documentation

* Add types

* Fix type doc

* Fix another type doc

* Fix another another type doc (is this one even right!?)

* Remove trailing comma

* Properly clone split options

* Add support for sending file as stream

* Missed a doc

* Resolve files only once when splitting messages

* This looks nicer

* Assign directly

* Don't cache data and files

* Missing return type

* Use object spread instead Object.assign

* Document constructors

* Crawl is a little dot

* comp pls

* tests: sanitize local file path, disable no-await-in-loop
2018-08-21 18:22:29 +02:00
Isabella
4ee3cf0b55 fix: WebhookClient should handle ratelimits properly 2018-08-21 11:12:02 -05:00
SpaceEEC
55c58b60e7 typings: fix PermissionResolvable typedef, allow resolving of Readonly<BitField<T>> 2018-08-21 16:12:01 +02:00
SpaceEEC
d91deefd79 fix(RequestHandler): DiscordAPIError#path should be the path, not the route 2018-08-21 12:05:33 +02:00
bdistin
c62f01f0e4 refactor(BitField): base class for Permissions, ActivityFlags, Speaking (#2765)
* abstract BitField from Permissions

* reduce useless code, improve docs

* add a ReadOnly identifier to the return type of Bitfield#freeze()

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#partial-readonly-record-and-pick

* fix the RangeError

* update docs, convert Speaking and ActivityFlags to bitfields

* fix some docs

* Fix Speaking BitField oops

* docs for oops

* more incorrect docs

* Fix incorrectly named property

* add new classes to index

* fix missing @extends docs

* default bitfield resolve to 0, and cleanup defaulting everywhere

Also removes GuildMember#missiongPermissions() alias that had incorrect behavior

* Breaking: Rename Overwrite allowed and denied to allow and deny

To be consistent with the api's naming

* fix setSpeaking usage to bitfields instead of booleans

* fix speaking bug in playChunk

* docs: Updated typings

* fix: BitFieldResolvable should use RecursiveArray

* bugfix/requested change

* typings: Cleanup (#2)

* typings: Fix BitField#{toArray,@@iterator} output type

* typings: correct PermissionOverwrites property names and nitpicks
2018-08-21 11:56:41 +02:00
Kyra
6be8172539 misc: add UNKNOWN_WEBHOOK error code (#2775)
* Add UNKNOWN_WEBHOOK error code

* docs: Update typings
2018-08-21 10:41:42 +02:00
Kyra
5787deef26 feat: GuildEmbed support (#2766)
* feat: Guild embed support

* docs: Fixed setEmbed's reason argument not being optional

* fix: Guild#setEmbed should return the guild itself for consistency

* docs: Updated typings

* fix: Requested change
2018-08-21 10:40:47 +02:00
Frangu Vlad
0401b8ad77 feat: handle and forward WEBHOOKS_UPDATE events (#2762)
* src: Handle WEBHOOK_UPDATE events

* Commit rename of 77'
Or adding the letter S

* I missed this

* Properly do this now
Typos everywhere

* Typings

* refactor: remove now unnecessary guild variable
2018-08-21 10:38:35 +02:00
Kyra
dc8cf08de9 backport: handle async stacktraces correctly (#2768) 2018-08-21 10:31:32 +02:00
Crawl
ab0ede0d5a fix: pin peer-deps to the latest version we allow 2018-08-20 18:43:53 +02:00
Crawl
8afc1fa545 fix: pin dev-deps to a higher version to avoid problems with upath on node 10 2018-08-20 18:38:26 +02:00
Crawl
f33ad64d12 chore: up ecmaVersion in eslint to support object rest spread 2018-08-20 18:30:19 +02:00
Frangu Vlad
4a24e8c12c Remove double iteration (#2773) 2018-08-19 13:37:00 +02:00
zajrik
68c832957d tests: Add typings lint runner to test script 2018-08-18 22:23:13 -05:00
Will Nelson
18d6be1eb3 update PR template (#2770)
* update PR template to encourage testing/typings

* add extra linebreak
2018-08-18 18:35:27 +02:00
SpaceEEC
7546ca3fe0 typings(Guild): add fetchVanityCode
PR: #2732
Commit: f8057b01cb
2018-08-18 17:22:57 +02:00
Florian
f8057b01cb feat: add guild.fetchVanityCode() (#2732)
* Error for guild.fetchVanityURL feature not enabled

* added GET/guilds/{guild.id}/vanity-url endpoint

* fix: code conventions

* adopted suggestion

* Changed error message according to change request

* Renamed method

to indicate that only the code is fetched, not the entire url.

* Update Guild.js
2018-08-18 13:57:58 +02:00
Frangu Vlad
94214fa733 misc: Remove Clyde (#2764)
* Remove Clyde

* Remove Clyde avatar overwrite

* Remove Clyde from the user pattern
2018-08-18 13:21:24 +02:00
zajrik
3b91fa0b49 tests(lint): Update typings lint script 2018-08-18 05:40:42 -05:00
zajrik
48f5a17fc4 cleanup(typings): Remove discord.js-test.ts
Useless file, filled with errors. Never served any real purpose. Discussed on discord. Can be replaced should a time come that we automate testing the typings further than just linting.
2018-08-18 05:35:09 -05:00
SpaceEEC
e7ee8d21d7 typings: VoiceState is extendable 2018-08-18 11:07:48 +02:00
SpaceEEC
58ce08255f typings: remove UserFlags and ClientApplicationCreateAssetsOptions
Leftover user bots declarations
2018-08-18 11:07:29 +02:00
SpaceEEC
c966aa2457 typings(VoiceRegion): remove no longer existing sampleHostname 2018-08-18 10:58:29 +02:00
Kyra
b2707e9ee5 cleanup(VoiceRegion): remove no longer existing sampleHostname (#2759) 2018-08-18 10:57:08 +02:00
Frangu Vlad
1e0379375e cleanup: remove more left-over selfbot constants (#2761)
* misc: Remove left-over selfbot stuff

* Forgot this
2018-08-18 10:55:09 +02:00
Frangu Vlad
e935611e50 fix(GuildBanAddHandler): not emitting guildBanAdd for uncached users (#2763) 2018-08-18 10:53:23 +02:00
zajrik
5fdd3a5877 tests(lint): Fix typings lint errors 2018-08-17 23:38:54 -05:00
zajrik
29d51fa582 tests: Fix typings lint script
Forgot to update it after moving the typings.
2018-08-17 23:11:06 -05:00
dependabot[bot]
e55f822ad4 build(deps-dev): update tslint requirement from ^3.15.1 to ^5.11.0 (#2745)
Updates the requirements on [tslint](https://github.com/palantir/tslint) to permit the latest version.
- [Release notes](https://github.com/palantir/tslint/releases)
- [Changelog](https://github.com/palantir/tslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/palantir/tslint/commits/5.11.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-08-17 23:07:08 -05:00
dependabot[bot]
418be7bef1 build(deps-dev): update tslint-config-typings requirement from ^0.2.4 to ^0.3.1 (#2746)
Updates the requirements on [tslint-config-typings](https://github.com/typings/tslint-config-typings) to permit the latest version.
- [Release notes](https://github.com/typings/tslint-config-typings/releases)
- [Commits](https://github.com/typings/tslint-config-typings/commits/v0.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-08-17 23:01:01 -05:00
SpaceEEC
6841b4e66a typings(VoiceConnection): receivers is now receiver and no longer an array
PR: N/A
Commit: e2726f5a9a
2018-08-17 16:58:41 +02:00
SpaceEEC
5942e8becc typings: remove user bots
PRs: #2559 #2758
Commits:
 - 5afd77ab73
 - 4999f675cd
2018-08-17 16:55:23 +02:00
Kyra
4999f675cd src: delete leftover UserConnection class (#2758) 2018-08-17 16:52:57 +02:00
bdistin
d437cecb3f Fix permission checking for Administrator channel overwrites (#2756) 2018-08-17 08:46:09 +01:00
Kyra
3f81b613d8 fix: Handle async stacks correctly (#2744)
* fix: Capture stack traces in APIRouter to preserve async stack

* fix: Handle the stack trace better

* fix: Check if error is an instance of Error (5XX rejects with Result)

* fix: Error.captureStackTrace is not supported in all browsers
2018-08-16 19:51:21 +01:00
Amish Shah
e2726f5a9a voice: remove createReceiver, just use VoiceConnection.receiver 2018-08-16 18:30:54 +01:00
Amish Shah
97c34b5b6f voice: clean up packet handling 2018-08-16 11:28:28 +01:00
Amish Shah
64832abfdb voice: clear connect timeout after connected (fixes #2752) 2018-08-15 14:25:47 +01:00
SpaceEEC
f5b3dff7f5 typings: make PermissionResolvable recursive 2018-08-15 15:13:08 +02:00
SpaceEEC
9a95b6a1e8 typings(Client): voiceStateUpdate now always has an old state
PR: N/A
Commit: 38597de271
2018-08-15 15:05:13 +02:00
Amish Shah
38597de271 voice: patch in default VoiceStateUpdate in case on doesn't exist, cache member 2018-08-15 14:02:11 +01:00
SpaceEEC
5d889be6db fix(Permissions): Permissions itself is a valid PermissionResolvable
fixes #2753
2018-08-15 13:55:04 +02:00
SpaceEEC
700201e3fe fix(GuildAuditLogs): default target to object with target_id (#2742) 2018-08-15 09:58:27 +02:00
SpaceEEC
616e0dd398 fix(Message): properly check for an edited_timestamp in patch
Fixes #2750
2018-08-15 09:18:17 +02:00
bdistin
6506252054 fix/refactor: fix GuildMember#presence getter and cleanup (#2751)
* Fix guild being a guild and not an AbstractHandler in PresenceUpdate

* update the default guild to be a Guild, and not GuildMember

* getters return null instead of undefined

* fix lint
2018-08-15 08:50:22 +02:00
Kyra
75254748b1 fix(Client): do not redefine _timeouts and _intervals of BaseClient (#2748)
Fixes an issue with the process permanently hanging.
2018-08-14 20:39:56 +02:00
SpaceEEC
9b5df571b3 refactor: typings for voice state and presences refactor
Commits: ea4375bf90...e0f52162ea
PR: N/A
2018-08-14 20:29:13 +02:00
bdistin
0ad7c24aa3 docs(User): fix hydrabolt's tag (#2747) 2018-08-14 19:09:10 +02:00
Amish Shah
e0f52162ea voice: allow for streaming silence to avoid audio glitches with repeated pausing/resuming (#2354) 2018-08-14 12:12:59 +01:00
Amish Shah
e666574f36 document GuildMember#voice 2018-08-14 11:50:11 +01:00
zajrik
efc8445260 refactor: Merge typings into 11.4-dev branch 2018-08-13 22:20:33 -05:00
zajrik
7864653df7 Add missing EOF newlines 2018-08-13 20:54:36 -05:00
zajrik
1ff56eb09d Merge typings into master 2018-08-13 20:51:41 -05:00
Schuyler Cebulskie
afcac9196d Update issue templates 2018-08-13 21:46:14 -04:00
Isabella
bb0700ade3 fix: Util#cleanContent parsing of GuildMember 2018-08-13 15:59:35 -05:00
Amish Shah
6852a15cee voice: fix StreamDispatcher#pause trying to call null function 2018-08-13 17:54:11 +01:00
Amish Shah
bfde1dd8f2 fix: StreamDispatcher doesn't emit finish if ended while paused (#2648) 2018-08-13 17:35:21 +01:00
Amish Shah
edf9c448fb fix: message passing empty data to GuildMember#_patch 2018-08-13 16:49:10 +01:00
Amish Shah
d276850c52 fix: GuildMemberStore now works with custom structures again 2018-08-13 16:21:11 +01:00
Amish Shah
332e30d31e fix: GuildMemberStore now patches existing members (#1870) 2018-08-13 16:02:05 +01:00
Amish Shah
ebfbf20f07 Bump to 11.4.2 2018-08-13 15:19:21 +01:00
Souji
3021e5ce7f Docs: document ChannelData.parent and .permissionOverwrites, fix typedefs to not include Collection of ChannelCreationOverwrite (#2734)
* document ChannelData.parent

* document ChannelData.permissionOverwrites

* Overwrites also take other things, account for it

* note to self: stop copy-pasting

* remove eslint madness, fix param defs

* fix property slip
2018-08-13 15:17:09 +01:00
Schuyler Cebulskie
b5df8603e8 Update version in web builds example 2018-08-12 17:01:32 -04:00
Kolkies
8b1bb95b1a docs: update for 11.4.0 (#2727)
* Update for 11.4.0 docs
2018-08-12 13:20:08 -05:00
Lewdcario
6775684ff0 chore: update typings & bump version 2018-08-12 13:14:52 -05:00
Lewdcario
d772bff632 fix(ClientDataManager): replacing channels unecessarily 2018-08-12 11:50:01 -05:00
Jacz
180813d3e8 Consistency with Getters. 2018-08-12 07:41:10 +01:00
Jacz
f9da255b44 More preformant way, forgot to commit this before whoops 2018-08-12 07:40:13 +01:00
Jacz
c1183f3534 Fixes VoiceChannel.members bug
Closes #2736
2018-08-12 07:40:13 +01:00
bdistin
b7e61f21ca fix(PresenceStore): pass user id as extra (#2733)
fix #2731
2018-08-11 18:24:30 +02:00
Amish Shah
e2ceea65ba Fix default presence for Users 2018-08-11 11:48:18 +01:00
Amish Shah
8ac664801c GuildChannel#setParent should allow channel to be a Snowflake (#2644) 2018-08-11 11:34:24 +01:00
Amish Shah
7968442dbf VoiceChannel#members should be a Collection, not an Array 2018-08-11 11:27:34 +01:00
Amish Shah
ea764afad2 add ClientPresence, remove ClientPresenceStore 2018-08-11 10:46:51 +01:00
Amish Shah
3c2eaff226 fix default presences again, remove redundant extras in PresenceStore 2018-08-11 10:19:31 +01:00
SpaceEEC
8adfc97409 docs(Client): actually fix rateLimit's event params 2018-08-11 09:38:58 +02:00
Amish Shah
f5ea673ebd fix default presence 2018-08-11 00:26:24 +01:00
Amish Shah
34ed3c6014 Update documentation for presenceUpdate 2018-08-10 17:09:05 +01:00
Amish Shah
e059581eee GuildMember#voice never undefined, improve documentation for VoiceState 2018-08-10 17:05:26 +01:00
Amish Shah
00ac62f975 chore: update typings 2018-08-10 16:59:01 +01:00
Amish Shah
08eff66939 Make presences track users and guilds, emit them in presenceUpdate 2018-08-10 16:46:14 +01:00
Amish Shah
fe8ece0192 voice state fixes 2018-08-10 15:15:52 +01:00
Amish Shah
df54d11dce Merge branch 'master' of https://github.com/hydrabolt/discord.js 2018-08-10 14:45:07 +01:00
Amish Shah
be5efea461 rewrite voice state handling 2018-08-10 14:44:59 +01:00
NbOpposite
ea4375bf90 Fixed splitting messages with codeblocks (#2720) 2018-08-10 15:44:32 +02:00
Kyra
0f63c50c06 fix: Util.basename being unreliable (#2679)
* fix: Util.basename being unreliable

new URL for WHATWG parsing was not chosen because it only works for URLs and threw in local pathes, path.basename is unreliable (according to the devs' note), and path.parse seems to work well.

* docs: Update Util.basename's description
2018-08-10 11:23:22 +02:00
Isabella
2c8e15e31c docs fix: RoleResolvable typedef missing and incorrecty documented methods (#2640)
* docs fix: RoleResolvable typedef missing and incorrecty documented methods

* requested changes???

* REAL requested changes

* shhh
2018-08-10 11:08:48 +02:00
Alex Hîncu
ce8a679a14 fix(Collection): use Symbol.species for creating derived collections (#2715) 2018-08-10 10:57:33 +02:00
Souji
0a21280990 add Collection as possible param to GuildChannel#overwritePermissions + wording port from 11.3-dev (#2719)
* add Collection as possible param to GuildChannel#overwritePermissions

* change PermissionoverwriteOptions desc. default to unset

* fix eslint hiccup

* fix spelling of snowflake
2018-08-10 10:57:05 +02:00
Yukine
147488df89 use null for getters (#2723) 2018-08-10 10:56:07 +02:00
Amish Shah
72bb9cb532 voice deps: fix prism-media requirement 2018-08-09 22:40:31 +01:00
Lewdcario
0e370d7a4c docs: fix client#rateLimit parameters 2018-08-09 14:58:17 -05:00
Lewdcario
7126cade45 fix: richEmbed#_apiTransform fields 2018-08-09 13:52:50 -05:00
Lewdcario
bef07152c8 chore: update typings & bump version 2018-08-09 11:47:52 -05:00
Amish Shah
16331d9e85 chore: update typings 2018-08-09 17:34:59 +01:00
Souji
bafbee9677 docs: small changes regarding permissions/overwrites (#2718)
* Add Collection as param to GuildChannel#replacePermissionOverwrites

* Add example for null to PermissionOverwriteOptions

* eslint-disable max-len

* PermissionOverwriteOptions desc. change default to unset

* deprecated allow/deny in favor of allowed/denied
2018-08-09 10:52:59 -05:00
Amish Shah
be56087c23 lint error 2018-08-09 14:00:33 +01:00
Amish Shah
ee6c19ca7e voice: rewrite GuildMember#speaking tracking (#2540) 2018-08-09 13:59:52 +01:00
Isabella
f3d7f7c3bd refactor: move Message#cleanContent function to Util (#2703)
* refactor: move Message#cleanContent function to Util

* suggested changes
2018-08-09 14:27:05 +02:00
1Computer1
8e0ea9aa16 Collection debug methods, remove deleteAll (#2577) 2018-08-09 14:25:07 +02:00
Amish Shah
55863efa15 voice: don't clear reject timeout until connection fully resolved (#2421, #2578) 2018-08-09 13:00:46 +01:00
Lewdcario
6da423fc07 backport: Permissions#toArray 2018-08-08 22:17:08 -05:00
Lewdcario
1e5b5b83c8 backport: GuildChannel#permissionsFor(role) 2018-08-08 22:16:46 -05:00
Lewdcario
c76f3048af backport: TextChannel#bulkDelete accepts Snowflake[] 2018-08-08 17:14:52 -05:00
Souji
af6d649510 docs: change for GuildChannel#replacePermissionOverwrites (#2714) 2018-08-08 16:09:39 -05:00
Lewdcario
9dfcb61a90 Revert "fix: Shards not receiving regular messages"
This reverts commit 88616eaf3e.
2018-08-08 13:03:29 -05:00
Amish Shah
8152841bab Try to cache members from data in message payloads 2018-08-08 12:45:49 +01:00
Crawl
5980d04f2b docs: implement #2707 on master 2018-08-08 12:48:34 +02:00
DennisV2809
47d405e70c Small typo in documentation of Message.js (#2704)
* Update Message.js

message.reply() example fix

* Update Message.js
2018-08-08 12:41:35 +02:00
SpaceEEC
c7f379f51d docs(RichEmbed): timestamp is actually a Date 2018-08-07 21:46:54 +02:00
SpaceEEC
4a48a7d621 docs(ShardingManager): respawnAll actually resolves with a collection of shards keyed by numbers 2018-08-07 21:36:03 +02:00
Amish Shah
98dc2df6d4 Revert "fix(Collection): use new this.constructor instead of new Collection (#2709)"
This reverts commit c10b4feeeb.
2018-08-07 19:08:51 +01:00
Amish Shah
382afee436 deps: update prism peer dep to point to right account 2018-08-07 18:25:42 +01:00
Amish Shah
46fa9603c2 voice: delete receive stream immediately to prevent it being written to after end (#2678) 2018-08-07 17:34:01 +01:00
Alex Hîncu
c10b4feeeb fix(Collection): use new this.constructor instead of new Collection (#2709) 2018-08-07 18:08:49 +02:00
Lewdcario
c33ab1ea61 backport: add PRIORITY_SPEAKER permission 2018-08-03 19:09:09 -06:00
Yukine
b38f537da8 feat: Add new Permission PRIORITY_SPEAKER (#2698) 2018-08-03 20:19:19 -04:00
Lewdcario
87b4b23596 backport: fix circular conversion when editing RichEmbed 2018-08-03 15:33:51 -06:00
Lewdcario
b63948e14e backport: RichEmbed#attachFiles 2018-08-02 15:06:27 -06:00
Frangu Vlad
4ae58f66f4 fix: Wrong _patch call from GuildEmoji#edit and other issues (#2673)
* Fix bugs

* Make the data.roles be undefined before API call

* Suggested changes

* Handle edit properly
2018-07-31 12:43:17 -04:00
Lewdcario
88616eaf3e fix: Shards not receiving regular messages 2018-07-31 09:55:32 -06:00
Will Nelson
9796489cbf remove hard-coded domain in welcome logo 2018-07-27 08:19:51 +01:00
Lewdcario
4a9c2f8884 fix(Emoji#fetchAuthor): reject with Error rather than TypeError 2018-07-26 14:35:26 -06:00
Lewdcario
41f6eaa635 backport: Message#url getter 2018-07-26 11:22:29 -06:00
Lewdcario
95a2d25b7d chore: deprecate userbot methods 2018-07-26 11:18:41 -06:00
Lewdcario
d685e39af4 backport: add rejection for Emoji#fetchAuthor if managed
Signed-off-by: Lewdcario <isabellafj97@gmail.com>
2018-07-26 10:24:26 -06:00
Lewdcario
96011cf68f backport: make Webhook token not enumerable 2018-07-26 09:51:47 -06:00
dependabot[bot]
92d753abe4 build(deps): update ws requirement to ^6.0.0 (#2670)
Updates the requirements on [ws](https://github.com/websockets/ws) to permit the latest version.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/commits/6.0.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-07-26 04:38:56 +02:00
Isabella
ba32eec7e8 feat(Message): add url getter (#2594)
* feat(Message): add jumpToURL getter

* fix url

* url syntax update

* name to url
2018-07-26 04:38:11 +02:00
bdistin
5afd77ab73 refactor: remove user bot methods (#2559)
* [WIP] Remove user bots

* more backend userbot removal

* Add mfaEnabled back

* revert client presences store removal

* partially revert getAuth changes

* remove more no longer used children of ClientUserGuildSettings

* fix a bug with this pr and TextBasedChannel.applyToClass

* remove a syncGuilds reference

* more user bot data handling

* various guildSync cleanup

* bots can't call logout

Had the user/bot portions of the code mixed up. Though, does this need to be a promise anymore?

* make ClientManager#destroy() sync

It nolonger needs to be a promise, and nothing depended on it being a promise that I can tell.

* requested change

* Fix massive error

* no longer used as it's userbot only
2018-07-25 22:14:23 -04:00
Yukine
f963621ef1 fix(GuildEmoji): added a check for managed emojis in fetchAuthor (#2645) 2018-07-25 21:11:38 -04:00
PLASMAchicken
c46cbbfd84 docs: added sizes 16, 32, 64 (#2666)
* documented sizes 16, 32, 64

* Removed space

* Added typedef

* The options to provide => Options for the Image URL

* fixed
2018-07-25 21:04:47 -04:00
Isabella
488b1eb4ee backport: Sharding utility methods (#2672) 2018-07-25 12:08:08 -04:00
Lewdcario
6d70da5b1e backport: fix circular conversion in RichEmbed 2018-07-23 22:41:07 -06:00
Lewdcario
e4da97e058 eslint: re-enable eslint after disabling max-len 2018-07-23 14:34:38 -06:00
Isabella
3a7a7d730b fix(MessageReaction): only delete reaction if cache and count is empty (#2661) 2018-07-23 16:32:51 -04:00
SpaceEEC
fbbd8f43b3 chore: update typing submodule 2018-07-22 20:37:38 +02:00
Gymnophoria
717e7f094a docs(Client): clarify messageReactionRemove event's user description (#2657)
* Clarify messageReactionRemove user description

* Update MessageReactionRemove.js

* wait one more word difference lol
2018-07-18 11:41:05 +02:00
SpaceEEC
36806612bf fix(Invite): support for group dm invites (#2603)
* fix(Invite): support group dm invites

* refactor(Invite): mark all optional properties as nullable and default them to null
2018-07-18 11:39:34 +02:00
SpaceEEC
886c21223e fix(GuildAuditLogs): default to PartialGuildChannel if channel deleted (#2605) 2018-07-18 11:38:59 +02:00
Kyra
e0378cf350 refactor(Webhook): make token not enumerable (#2566)
* Hide Webhook#token (consistency with Client#token)

* Make `Webhook#token` writable

* fix: devsnek's requested change

Webhook#token must be both writable and configurable.
2018-07-18 11:37:57 +02:00
Gymnophoria
a97b5040e6 docs(Client): clarify messageReactionRemove event's user description (#2657)
* Clarify messageReactionRemove user description

* Update MessageReactionRemove.js

* wait one more word difference lol
2018-07-18 11:37:36 +02:00
Lewdcario
524a15df0b backport: Permissions improvements 2018-07-17 21:49:21 -05:00
Lewdcario
0702a0fcda backport: DefaultMessageNotifications 2018-07-17 21:32:24 -05:00
SpaceEEC
3d25277839 chore: update typings submodule 2018-07-15 08:42:40 +02:00
Amish Shah
7d2744be89 voice: use development version of prism 2018-07-12 16:11:04 +01:00
Lewdcario
f67d682223 fix(ShardingManager): respawnAll shard iteration 2018-07-10 21:39:58 -05:00
SpaceEEC
1d9edec567 fix(Message): keep reply option when replying with an embed or attachment
Fixes #2651
2018-07-08 21:40:12 +02:00
SpaceEEC
526832058e fix(Message): keep reply option when using an embed or attachment
See #2651
2018-07-08 21:12:30 +02:00
Amish Shah
d81441f627 voice: null-check UDP socket 2018-07-03 14:15:27 +01:00
Amish Shah
695ff1e70f voice: fix #2635 (channel bitrate not being set) 2018-07-02 19:45:35 +01:00
Souji
95b2dd3fe6 feat: Add support for Guild#setDefaultMessageNotifications (#2624)
* Feat: Guild#setDefaultMessageNotifications

* fix typo
2018-07-01 11:03:47 -05:00
Lewdcario
077d41fbca fix(Webhook): import Channel correctly 2018-07-01 10:19:44 -05:00
Lewdcario
938d87d5d6 fix(Shard): actually remove default execArgv 2018-07-01 10:17:20 -05:00
Lewdcario
a667e44c4d fix(Client): login catch 2018-07-01 10:05:56 -05:00
Lewdcario
3d82ca901b docs: improvements in various places
* Client#login example consistency

* add warning to Client#fetchApplication

* incorrect WEBHOOK_DELETE value
2018-06-29 19:38:20 -05:00
Lewdcario
448f38429d fix(Client): login not properly rejecting on invalid token 2018-06-29 19:38:06 -05:00
Lewdcario
3fa9ed1f42 backport: deleted property 2018-06-29 19:11:50 -05:00
Lewdcario
72346fb47e fix(TextBasedChannel): bulkDelete should not return non-Promise 2018-06-29 17:32:56 -05:00
Lewdcario
2694c0d442 fix(RequestHandler): provide proper route and method 2018-06-29 15:13:03 -05:00
Lewdcario
93f8c8547b fix(Shard): allow node to default to process.execArgv 2018-06-29 15:13:01 -05:00
Lewdcario
92e2c3c7fd fix: instantiate constructors before using those properties 2018-06-29 15:12:52 -05:00
Lewdcario
41a1dee533 fix(Util): circular reference 2018-06-29 13:02:38 -05:00
dependabot[bot]
bcdb8011e3 build(devDeps): update eslint requirement to ^5.0.1 (#2629)
* build(devDeps): update eslint requirement to ^5.0.1

Updates the requirements on [eslint](https://github.com/eslint/eslint) to permit the latest version.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/commits/v5.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>

* fix(eslint): disable getter-return rule
2018-06-26 23:14:54 +02:00
bdistin
f711aa35ac fix: typo in src/errors/messages.js (#2631)
fixes #2630
2018-06-26 19:07:09 +02:00
Lewdcario
6b3bfdd7de fix(Shard): fix default args 2018-06-25 16:10:50 -05:00
FireController1847
ac0c15f7f1 Change ytdl example (#2619) 2018-06-24 15:47:54 +02:00
Isabella
bfbb723f42 feat(ShardingManager): add execArgv option (#2585) 2018-06-23 16:09:03 -05:00
bdistin
58e5017159 fix: ratelimits (#2615)
* Add timeDifference calcs back into ratelimits

And fix x-ratelimit-reset is in seconds, not ms: https://puu.sh/AIXxY/9b3989b248.png

* mutate reset time with date header instead

* fix defaulting of reset and remaining

if the reset header is not available, then the reset time should be Date.now() instead of the difference between the date header and Date.now()

If the date header is null, fall back to Date.now() since it's the best we can do (this should never happen, but safer to handle it just in case)

if remaining is 0 we don't want to default it back to 1 since 0 is falsy
2018-06-23 16:08:40 -05:00
Souji
de408d735b docs(Guild): memberCount is not as of ready (#2621)
but updated every guild member add or remove
2018-06-23 15:22:57 +02:00
Mikhail
bf738b34de fix(BasePlayer): incorrectly mutating FFMPEG_ARGUMENTS when using seek (#2622)
Because args was not a copy of FFMPEG_ARGIMENTS, but a reference to it, pushing 'ss' argument pushed it to FFMPEG_ARGUMENTS, making it persistent.
2018-06-23 15:20:59 +02:00
Amish Shah
18646b72f9 voice: use getters where possible 2018-06-22 18:46:51 +01:00
Amish Shah
08bbbe9301 voice: handle new client_connect and client_disconnect packets 2018-06-22 18:38:33 +01:00
Amish Shah
9296a30148 voice: account for speaking now being a bitmask 2018-06-22 17:47:00 +01:00
Amish Shah
1f7c1ddaa2 voice: start update to v4, fix heartbeats 2018-06-22 17:42:04 +01:00
Amish Shah
3d41748a38 voice: fix not passing volume to transform constructor 2018-06-21 21:50:54 +01:00
Camzure
7ce1d1642c docs: only cached messages emit reaction events (#2607)
* wording improvement

* wording improvement for docs

* docs: wording

* wording

* user account only: docs

* Edited

* Edited

Signed-off-by: SpaceEEC <spaceeec@yahoo.com>
2018-06-21 21:40:52 +02:00
Camzure
9997a67ab6 Docs: Wording Improvements (#2607)
* wording improvement

* wording improvement for docs

* docs: wording

* wording

* user account only: docs

* Edited

* Edited
2018-06-21 21:35:52 +02:00
SpaceEEC
8a3ae875bb fix: do not cache webhook users (#2611)
Goal in mind is to not save the name and avatar used by webhooks because
those can change between messages without any other update.
2018-06-21 21:34:30 +02:00
SpaceEEC
bd3d8d48c0 docs(GuildMember): joinedAt is nullable
See: ecf6e2b62d
2018-06-21 21:24:53 +02:00
Will Nelson
594363a05e fix response parsing (#2614)
* fix response parsing

* rfc: better parseResponse function
2018-06-21 00:11:47 +02:00
Amish Shah
99a9a813d7 voice dep: bump prism-media to 0.3.0 2018-06-20 20:44:27 +01:00
Kyra
270a278a6e feat(Guild): add support to edit defaultMessageNotifications level (#2592)
* Added support for `defaultMessageNotifications`

* Requested changes

* docs: Change type for GuildEditData.defaultMessageNotifications
2018-06-19 21:16:05 +02:00
Will Nelson
5e011dbc11 switch to node-fetch (#2587)
* switch to node-fetch

* remove useless var declaration

* remove method uppercasing

* rework concurrency

* Revert "rework concurrency"

This reverts commit ef6aa2697e.

* fix headers
2018-06-19 20:10:55 +02:00
Souji
791f58e130 docs: add video to MessageAttachment properties (#2608) 2018-06-19 20:09:55 +02:00
RumbleFrog
c5fea45f30 fix(ShardClientUtil): send method erroneously rejecting (#2604) 2018-06-17 19:47:42 +02:00
RumbleFrog
493ba73037 fix(ShardClientUtil): send method's promise erroneously rejecting (#2604)
Patches the remaining ones that were missed in eef4a4ad17
2018-06-17 08:21:51 +02:00
Schuyler Cebulskie
d97af9d2e0 Improveder 2018-06-17 00:51:32 -04:00
Schuyler Cebulskie
f91747a764 Improve Shard#kill description 2018-06-17 00:50:38 -04:00
reeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
e7eab427e5 docs: document lastMessageID for TextChannel and (Group)DMChannel (#2602)
* Adds JSDocs for TextChannel.lastMessageID

* oops

* docs: document lastMessageID in (Group)DMChannel as well
2018-06-16 22:28:12 +02:00
reeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
507cce3ff4 docs: document lastMessageID for TextChannel and (Group)DMChannel (#2602)
* Adds JSDocs for TextChannel.lastMessageID

* oops

* docs: document lastMessageID in (Group)DMChannel as well
2018-06-16 22:10:24 +02:00
bdistin
037e8cf969 fix(Messages): undeleting themselves (#2570)
when a _patch() is queued
2018-06-16 21:16:57 +02:00
Kyra
e8ab049a67 refactor(MessageMentions): make client, guild, and _content non enumerable 2018-06-16 17:14:10 +02:00
Will Nelson
56f461a8b5 use new multiple issue templates (#2600) 2018-06-16 10:02:48 +02:00
Amish Shah
1cdee7b48a voice: reimplement seek option (#2572) 2018-06-13 21:16:14 +01:00
Amish Shah
04618f554f voice: fix _writeCallback being called multiple times (#2567) 2018-06-13 21:06:50 +01:00
Amish Shah
3bfc1ff61c voice: fix write after end (#2567) 2018-06-13 21:02:19 +01:00
Amish Shah
d69e906027 voice: fix voice receive after enabling suffix and lite encryption modes 2018-06-13 20:43:18 +01:00
SpaceEEC
14eadb3ce0 chore: update submodule 2018-06-13 08:54:44 +02:00
Lewdcario
ba9a93b0bf docs: last english fix for now 2018-06-12 18:54:51 -05:00
Lewdcario
eb4607c8ad docs: fix english because english is difficult 2018-06-11 21:18:15 -05:00
Lewdcario
5eff360a4d docs: wording improvements 2018-06-11 16:37:34 -05:00
iDroid
bce9a8af1b feat(User): add locale property (#2571) 2018-06-10 10:58:00 -05:00
bdistin
99bd355522 refactor: RESTManager handlers to use collection (#2539) 2018-06-10 05:45:34 +02:00
Lewdcario
6de5acbac3 backport: RichPresence 2018-06-09 15:37:01 -05:00
Lewdcario
ecf6e2b62d fix(GuildMember): mark joined as nullable 2018-06-09 15:15:08 -05:00
dependabot[bot]
fc96cfbc00 Revert "build: update snekfetch requirement to ^4.0.1 (#2580)"
This reverts commit 46af6e3396.
2018-06-06 09:09:27 -06:00
Lewdcario
5071477172 fix(GuildMember): account for joinedTimestamp as well 2018-06-05 20:14:34 -05:00
Lewdcario
13bfceb83c fix(GuildMember): mark joined as nullable and fix fetching for these cases 2018-06-05 19:50:36 -05:00
dependabot[bot]
46af6e3396 build: update snekfetch requirement to ^4.0.1 (#2580)
Updates the requirements on [snekfetch](https://github.com/devsnek/snekfetch) to permit the latest version.
- [Release notes](https://github.com/devsnek/snekfetch/releases)
- [Commits](https://github.com/devsnek/snekfetch/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-06-05 09:26:20 +02:00
Lewdcario
c8ecbe6585 docs: GuildMember#speaking
and consistency improvements
2018-06-05 00:33:54 -05:00
Lewdcario
09708482f6 fix(ReactionUserStore): fetch inconsistency
It should be consistent with MessageStore#fetch now
2018-06-05 00:33:52 -05:00
Lewdcario
dfbd4bdde1 docs: add examples & improve notices 2018-06-05 00:33:43 -05:00
Lewdcario
caa4104b95 docs: GuildMember#speaking
closes #2540
also improves consistency
2018-06-05 00:31:06 -05:00
Lewdcario
f238883046 fix(MessageReaction): fetchUsers inconsistency
Unlike TextChannel#fetchMessages, this method returned the cache rather than the fetched items, so in interests of consistency, this does as well now
closes #2574
2018-06-05 00:31:03 -05:00
Lewdcario
eef4a4ad17 fix(Shard): erroneously returning false
The node documentation fails to correctly document when the backlog of unsent messages exceeds a certain threshhold the function will return false. This does not mean it will refuse to send- simply that it will take time. Issue in point: https://github.com/nodejs/node/issues/7657#issuecomment-240581726
2018-06-05 00:31:00 -05:00
Lewdcario
c699888780 docs: add examples & improve notices 2018-06-05 00:30:50 -05:00
Lewdcario
512af54e5d fix(Shard): erroneously returning false
The node documentation fails to correctly document when the backlog of unsent messages exceeds a certain threshhold the function will return false. This does not mean it will refuse to send- simply that it will take time. Issue in point: https://github.com/nodejs/node/issues/7657#issuecomment-240581726
2018-06-04 18:01:10 -05:00
Lewdcario
0387d34ab4 fix(VoiceChannel): deletable erroneously returning true 2018-06-04 17:18:27 -05:00
Lewdcario
0be0d2542d fix(VoiceChannel): deletable erroneously returning true 2018-06-04 17:16:35 -05:00
Lewdcario
46b19bbbdb fix(GuildMember): Invalid Date 2018-06-04 16:24:42 -05:00
dependabot[bot]
276109ed3c build: update webpack-cli requirement to ^3.0.1 (#2579)
Updates the requirements on [webpack-cli](https://github.com/webpack/webpack-cli) to permit the latest version.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/commits/v3.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-06-04 09:26:10 +02:00
SpaceEEC
faf27fabc0 chore: update typings submodule 2018-05-29 11:24:02 +02:00
Kyra
d02c303afd fix(Guild): equals method modifying features array of guild (#2544)
* Fixed a bug where Guild#equals would cause the given guild to lose its features

* Fix Util.arraysEqual

* Fixed docs for Util.arraysEqual

* Remove Util.arraysEqual
2018-05-29 11:15:19 +02:00
Kyra
30c7d6d1b1 feat(Guild#defaultMessageNotifications) (#2538)
* feat(Guild#defaultMessageNotifications)

* boolean -> DefaultMessageNotifications

* Space's requested change
2018-05-28 17:44:04 -05:00
Braxton
f0c4d0e834 feat: Add "deleted" property to multiple structures. (#2556)
* Add "deleted" property to "Message" structure

* Add "deleted" property to Multiple structures

Structures edited:
- Channel
- Emoji
- Guild
- Guild Member
- Role

* Update "deletable" getter

* Fix ESLint "no-trailing-spaces" errors

* Requested Change: Mark w/ bulkDelete
2018-05-28 17:42:51 -05:00
Adrien Brignon
13880fe7de docs(Guild): handle error in example of fetchInvites correctly (#2568) 2018-05-27 20:59:12 +02:00
Adrien Brignon
27fcb64187 docs(Guild): handle error in example of fetchInvites correctly (#2568) 2018-05-27 20:57:50 +02:00
Dim
5494f8e3bd Fix: Incorrect NSFW Status on Channels (#2499)
* Fix #2498

* wow this code seems familiar

* please be the last iteration
2018-05-27 03:57:33 -05:00
Will Nelson
fc81924724 feat: Shard#kill method (#2454)
* add shard#kill method

* docs consistency
2018-05-27 03:26:18 -05:00
SpaceEEC
14aab1be38 fix(RequestHandler): only retry once on 5xx (#2471) 2018-05-25 17:33:17 +02:00
SpaceEEC
f23b61794c fix(ClientUser): correctly resolve nicks to an object in createGroupDM 2018-05-25 17:23:09 +02:00
SpaceEEC
f456f4c3c0 feat(Collection): backport partition method
Commit: a732402c95
PR: #2511
2018-05-25 16:49:10 +02:00
SpaceEEC
f921261f3f fix(docs): remove duplicated Collection#findAll docstring
Also added intended @ deprecated decorators
2018-05-25 16:44:49 +02:00
SpaceEEC
56a9d1ba3c docs(Collection): make findKey method show up in docs
Solved by moving the eslint-enable line below the method header.
2018-05-19 08:50:39 +02:00
bdistin
25b654d494 consistency is king (#2554) 2018-05-18 03:30:19 +02:00
Lewdcario
75747f5b18 fix: RequestManager getting stuck on global ratelimit
fixes #2550
2018-05-14 22:55:50 -05:00
1Computer1
a732402c95 refactor: remove unnecessary Collection methods and add Collection#partition (#2511)
* Rework collection

* Fix docs

* Remove (prop, value) behavior

* Add back thisArg

* Put examples on same line

* Revert map to return array

* Make examples less specific

* Add thisArg to sweep and partition
2018-05-14 01:15:43 -05:00
Lewdcario
6070b22382 docs: using deprecated version of find 2018-05-13 04:41:58 -05:00
Lewdcario
b2d1cb6a3d docs: permissions 2018-05-12 00:51:08 -05:00
Lewdcario
09ddbcb88a chore: deprecations 2018-05-12 00:40:12 -05:00
Lewdcario
6f02be2b2e docs: rateLimit event 2018-05-11 23:21:39 -05:00
Lewdcario
0d90798c6c backport: rateLimit event 2018-05-11 20:55:31 -05:00
Lewdcario
379061987c fix: burst request mode hanging permanently 2018-05-11 19:27:34 -05:00
SpaceEEC
75ebd5d23c chore: update typings submodule 2018-05-10 16:34:03 +02:00
Amish Shah
43c92c13e2 voice: support xsalsa20_poly1305_lite and xsalsa20_poly1305_suffix 2018-05-10 12:11:22 +01:00
Amish Shah
685814aa61 voice: make sure speaking is false when paused 2018-05-09 18:44:46 +01:00
1Computer1
de7d90ada3 feat(Collection): add tap method (#2507)
* Add Collection#inspect

* No u

* Rename to tap

* Rename variable

* Do it here too
2018-05-09 16:46:54 +02:00
bdistin
2b6592ed54 feat(Collection): add sweep method (#2528) 2018-05-09 16:42:28 +02:00
SpaceEEC
9bb8831619 feat(GuildMember): add manageable getter 2018-05-09 16:38:28 +02:00
SpaceEEC
99041671f0 feat(GuildChannel): add fetchInvites method
Backported from commit: 47bc0fc51e
PR: #2339
2018-05-09 16:28:40 +02:00
SpaceEEC
dd7eedbd48 feat(Emoji): add fetchAuthor method
Backported from commit: e0cbf0bb60
PR: #2315
2018-05-09 16:20:41 +02:00
SpaceEEC
c0ca73a40c feat(Game): add toString method
Backported from commit: 016526486c
PR: #2313
2018-05-09 16:08:59 +02:00
SpaceEEC
15a8e17710 fix(Guild): memberCount not decrementing when an uncached member leaves
Backported from commit: 93e083da4f
2018-05-09 16:07:20 +02:00
SpaceEEC
54913d9edb feat(GuildChannel): add setNSFW method
Backported from commit: 0fc9459450
PR: #2050
2018-05-09 16:04:49 +02:00
Gus Caplan
9169958264 feat(Guild): add verified getter (#2027) 2018-05-09 15:52:00 +02:00
Amish Shah
841b9de918 voice: mark speaking as false when paused, prevent repeated pausing 2018-05-09 14:33:23 +01:00
SpaceEEC
96b115ef7b feat(ClientDataResolver): add 2 basic role colors
Commit: 3a3ca96b0d
PR: #2303
2018-05-08 22:35:35 +02:00
Will Nelson
2d831269ab feat(Permissions): add valueOf method (#2363) 2018-05-08 22:30:27 +02:00
Jonah Snider
e5e59cce32 docs(Role): Change 'the this' to this (typo) (#2377)
Commit: 8b679913a4
2018-05-08 22:27:58 +02:00
Pascal
ae28f52e0d fix(ClientDataResolver): always resolve with a buffer when fetching a file
Commit: 85413481ed
2018-05-08 22:25:49 +02:00
SpaceEEC
9264511092 docs(ClientUser): correct warning for createGuild method
Backported from: 2bf68dcdfb
PR: #2453
2018-05-08 22:06:07 +02:00
SpaceEEC
2f2e28183b fix(Role): allow role color to be removed
Backported from: f985b6bef3
PR: #2447
2018-05-08 22:05:56 +02:00
SpaceEEC
54fa5f644f docs(GroupDMChannel): fix top 'an user' -> 'a user' 2018-05-08 20:14:23 +02:00
bdistin
b757f9ef2d docs(Collection): fix spelling of 'behavior' (#2529) 2018-05-08 19:07:49 +02:00
Kyra
bd9c9ce4e0 refactor(VolumeInterface): remove usage of deprecated new Buffer (#2531) 2018-05-08 18:55:52 +02:00
SpaceEEC
60288d0704 fix(Collector): increase and decrease max listeners dynamically 2018-05-08 11:57:12 +02:00
SpaceEEC
ed8ab91782 feat(Emoji): add deletable getter
Backport for commit: fca6d3be56
From PR: #2535
2018-05-08 11:35:14 +02:00
SpaceEEC
6cde6decee fix(GuildEmoji): verify MANAGE_EMOJIS permission from Guild#me 2018-05-08 11:29:36 +02:00
Kyra
fca6d3be56 feat(GuildEmoji): add deletable getter (#2535)
* feat(GuildEmoji#deletable)

* Update: Discord API returns 50001

When you try to get or delete a managed emoji from the API, you get a 50001 (Missing Access) error code.
2018-05-06 21:12:16 +02:00
SpaceEEC
21326f67a0 feat(ClientDataResolver): account for discord.gg/invite/<code> invites 2018-05-04 18:49:53 +02:00
SpaceEEC
90312952d9 revert: "Improved TextBasedChannel#send (#2537)"
This reverts commit 556e679bdb,
which broke resolving of non object literal message options.
2018-05-04 16:44:06 +02:00
Kyra
556e679bdb Improved TextBasedChannel#send (#2537) 2018-05-04 14:56:22 +02:00
bdistin
7a3a4d1388 feat: add Collection#sweep() (#2528) 2018-05-04 02:27:59 -05:00
Will Nelson
32369f3bdd fix: prevent max listener problems with collectors (#2521) 2018-05-04 02:11:52 -05:00
1Computer1
9f918199d2 feat: add Collection#tap (#2507)
* Add Collection#inspect

* No u

* Rename to tap

* Rename variable

* Do it here too
2018-05-04 02:08:32 -05:00
Kyra
8700e965c5 feat(DiscordAPIError): backport method property (#2536) 2018-05-03 22:47:50 +02:00
SpaceEEC
ddab8096cf feat(DataResolver): account for discord.gg/invite/<code> invites 2018-05-03 21:09:55 +02:00
Kyra
42ce4f8bc0 Removed usage of (deprecated) new Buffer (#2531) 2018-05-03 19:07:16 +02:00
dependabot[bot]
21cc2952eb build: update @types/node requirement to ^10.0.3 (#2532)
Updates the requirements on [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped) to permit the latest version.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-05-03 19:03:42 +02:00
Kyra
a89de09855 fix(RESTMethods): remove listener from correct event (#2534) 2018-05-03 17:56:10 +02:00
Kyra
62605c4470 feat(DiscordAPIError): add method property (#2530) 2018-05-03 08:01:27 +02:00
bdistin
17d2c2efb8 docs(Collection): fix spelling of 'behavior' (#2529) 2018-05-03 08:00:56 +02:00
Lewdcario
f293dddc29 fix: Webhook#edit attempting to use client.channels always 2018-05-02 21:19:00 -05:00
Amish Shah
bd83bb9fd6 refactor: improve sweep performance 2018-05-02 18:09:51 +01:00
Amish Shah
27a0f48441 refactor: tidy up _inactive check 2018-05-02 18:04:47 +01:00
Amish Shah
b5f37728a7 feature: allow sweeping of inactive request buckets 2018-05-02 17:57:48 +01:00
SpaceEEC
a85d801a12 fix(ClientUser): setActivity should resolve with a Presence 2018-05-01 20:27:05 +02:00
Lewdcario
745669a7c9 docs: consistency 2018-04-29 13:28:12 -05:00
Amish Shah
5f50d9e627 voice: backport null key fix 2018-04-29 18:53:50 +01:00
Frangu Vlad
5acf4061e8 fix: GuildMember#toJSON not having roles (#2520) 2018-04-29 11:28:45 -05:00
Kyra
934e90b921 fix: Added everyone role to GuildMemberRoleStore#_filtered (#2514)
* Added everyone role to GuildMemberRoleStore#_filtered

* Changed to Guild#defaultRole
2018-04-28 13:40:24 -05:00
SpaceEEC
33a4232652 fix(OpusEngineLinst): throw a descriptive error when not funding an opus engine 2018-04-28 14:30:14 +02:00
SpaceEEC
d9a091f674 feat(SnowflakeUtil): allow snowflakes to be generated dynamically 2018-04-27 20:34:48 +02:00
SpaceEEC
44fefdfa49 fix(Util): reject with a meaningful error instead of throwing one 2018-04-27 20:16:46 +02:00
Amish Shah
0eb6409504 voice: remove krypton submodule 2018-04-27 15:45:53 +01:00
Amish Shah
b05622766b voice: start using provided IP rather than manually resolving 2018-04-27 15:25:05 +01:00
Amish Shah
299fc001d5 voice: start using provided IP rather than manually resolving 2018-04-27 15:11:37 +01:00
Isabella
49ad8cc2cc feat(GuildChannel): add manageable getter (#2439)
* Adds GuildChannel.manageable

* Resolve requested changes

* fix eslint max-len error

* Fix for nullable permissionsFor()

* Indent fixes
2018-04-26 01:31:52 -05:00
bdistin
7b9e84dff5 feat(Guild): add mfaLevel property (#2451) 2018-04-26 01:28:59 -05:00
Lewdcario
384e96d51e backport: docs improvements 2018-04-26 01:25:44 -05:00
Isabella
d7e7803178 docs: (backport) Bring the main doc pages up to date, and add more examples (#2094) 2018-04-26 01:13:44 -05:00
Lewdcario
64caa33594 fix: GuildEmoji#clone 2018-04-25 18:42:51 -05:00
Lewdcario
30d43efa54 fix: GuildMemberRoleStore#remove 2018-04-25 18:01:28 -05:00
Daniel Odendahl Jr
95b531742a fix: TypeError in mixin function (#2506) 2018-04-24 18:35:07 -05:00
Isabella
8b83553462 refactor: role stores (#2478)
* refactor: reduced duplication in role stores

* fix docs

* fix: typo

* most of requested changes

* rest of changes

* ACTUAL rest of changes

* docs

* doooocs

* reason
2018-04-24 15:52:00 -05:00
Jacz
e12ab7428f fix(MessageEmbed): correct docs, default to array, resolve MessageAttachments (#2492)
* Fix(MessageEmbed): Remove useless for...of & change this.files to be out of the data.files check...

* Requested changes
2018-04-23 19:38:56 +02:00
Kyra
b186472785 Added a note in userUpdate event (#2479) 2018-04-21 21:45:15 +02:00
Lewdcario
b8a9a76cf6 docs: inconsistencies 2018-04-20 21:10:21 -05:00
bdistin
feb0991c46 fix: use Object.keys instead of Object.values for node 6 (#2487) 2018-04-20 21:11:27 +02:00
Faith
c9c2d66971 feat(GuildChannelStore): add topic to create options (#2488)
The API provides the ability to send the topic, or description, of the channel within the creation post. Discord.js will now send it if its provided.
2018-04-20 19:11:46 +02:00
SpaceEEC
ff671b2f3c fix(RestMethods): typo timeout -> timed 2018-04-19 13:53:44 +02:00
SpaceEEC
b60ee25038 fix(MessageEmbed): avoid throwing error when accessing colorless hexColor 2018-04-19 13:14:20 +02:00
SpaceEEC
3ba26ad972 fix(Message): do not update editedTimestamp when there is none in the payload
Fixes #2307
2018-04-19 13:13:50 +02:00
SpaceEEC
de78a8d0b4 fix(RESTMethods): verify correct member in add and remove role listeners
Fixes #2480
2018-04-19 13:13:28 +02:00
SpaceEEC
7c37a0d386 fix(MessageDeleteBulkAction): remove bulkDeleted messages from cache
Fixes #2382
2018-04-19 11:50:30 +02:00
Lewdcario
c387e96078 fix: Client#generateInvite resolving permissions incorrectly 2018-04-18 20:30:24 -05:00
Lewdcario
8d065fa043 fix: Client#generateInvite resolving permissions incorrectly 2018-04-18 20:25:49 -05:00
Lewdcario
ec9211c3ce docs: inconsistencies 2018-04-18 20:21:17 -05:00
Lewdcario
7c0b6173dd fix: Role#setPermissions resolving & docs 2018-04-18 19:57:16 -05:00
Lewdcario
92b421607e fix: GuildChannel#setTopic not nullable 2018-04-18 19:35:28 -05:00
iDroid
f3ae7fd638 Fixed JSDoc owner thing (#2473)
Added a `?` before `GuildMember`, the `owner` property may be undefined in some cases.
2018-04-18 19:25:28 -05:00
Suvan
2dd7fd2739 docs(GroupDMChannel): fix grammar an user -> a user (#2482) 2018-04-17 18:24:48 +02:00
SpaceEEC
f6216f3905 feat(SnowflakeUtil): allow snowflakes to be generated dynamically (#2459) 2018-04-17 09:00:18 -05:00
bdistin
8551b8936c docs: fix a number of spelling mistakes (#2469) 2018-04-13 20:50:47 +02:00
Pascal
6069061fee chore: update typings submodule 2018-04-13 19:50:59 +02:00
sekwah41
6e5b674338 Fixed updateChannel being too protective (#2460)
If I am not mistaken the only way atm to remove a channels parent atm is to do this to get the null value through the code.

channel.client.rest.methods.updateChannel({id:channel.id, name:channel.name,
            topic:channel.topic,position:channel.position,
            bitrate:channel.bitrate,userLimit:channel.userLimit,parent:{id:null}}, {});

This fixes the method allowing channel.setParent(null); to work
2018-04-13 14:03:18 +02:00
Frangu Vlad
61ad9475de fix(ClientManager): patch ClientUser's presence with ClientOption's one (#2458) 2018-04-13 08:27:53 +02:00
Crawl
f2474845ba fix: webpack building and upgrading to webpack 4.5 2018-04-11 13:49:42 +02:00
Amish Shah
cb69102e5e voice: allow for changing volume with webm/ogg streams 2018-04-10 21:19:29 +01:00
Jérémie N'gadi
e845758037 fix(StreamDispatcher): only update speaking for non broadcasts (#2437)
If the player is a BroadcastAudioPlayer it has no VoiceConnection directly associated with it.
2018-04-09 21:17:16 +02:00
Schuyler Cebulskie
952a7123f3 Add missing word in Shard#respawn docblock 2018-04-09 14:35:49 -04:00
Pascal
b955a514f6 fix(Guild): remove member's voice state on guildMemberRemove
fixes #2430
2018-04-09 17:43:07 +02:00
bdistin
b3ff7c728e feat(Guild): add mfaLevel property (#2451) 2018-04-09 09:56:48 +02:00
bdistin
2bf68dcdfb docs(GuildStore): correct warning for create method (#2453)
Bots may create guilds if they are in less than 10 guilds.
2018-04-09 09:56:25 +02:00
Frangu Vlad
f985b6bef3 fix(Role): allow edit method to null the color (#2447) 2018-04-09 09:54:40 +02:00
Amish Shah
ef138fd3e9 voice: fix #2380 (voiceSessionID null after changing server region) 2018-04-07 15:29:38 +01:00
Amish Shah
fa886eaae9 voice: fix bug where no audio could be heard if voice region changed 2018-04-07 15:19:18 +01:00
Amish Shah
384fdf8f17 voice: properly cleanup after disconnect (#2443, #2435, #2421, #2406 #2359) 2018-04-07 14:40:05 +01:00
Amish Shah
41d0f25d0f voice: fix heartbeat issue (#2443) 2018-04-05 16:38:35 +01:00
Pascal
e431ccdad2 fix(GuildChannel): always return a boolean from the manageable getter
Overlooked the comment pointing that out in #2439
2018-04-02 20:52:12 +02:00
Favna
ef4bd92c8a feat(GuildChannel): add manageable getter (#2439)
* Adds GuildChannel.manageable

* Resolve requested changes

* fix eslint max-len error

* Fix for nullable permissionsFor()

* Indent fixes
2018-04-02 20:00:47 +02:00
Amish Shah
a5e8f05d01 voice: add end param to describe how a voice receive stream should end 2018-03-31 11:52:48 +01:00
Schuyler Cebulskie
623d4c0076 Add deploy exception for dependabot branches 2018-03-25 15:14:18 -04:00
Will Nelson
b5b436f9cb Revert "fix message embed json serialization (#2420)"
This reverts commit c40488eb54.
2018-03-24 18:47:15 -06:00
Will Nelson
c40488eb54 fix message embed json serialization (#2420)
* fix message embed json serialization

remove the toJSON method on message embeds so the raw data is exposed
for JSON seralization. this removes the hexColor property, but it
probably should not have been there in the first place. fixes #2419

* change api transform to tojson
2018-03-24 19:43:56 -05:00
Lewdcario
4e0e64d8a1 fix(MessageReaction): inaccurate count
also works towards async rewrite goal
fixes #2404
2018-03-24 15:22:21 -06:00
Pascal
d041cb2460 fix(GuildEmojiRoleStore): do not prematurely patch roles
Issue is the same as in #2312 and #2381, but for the GuildEmojiRoleStore.
Thanks to @KingDGrizzle for pointing this out.
2018-03-16 20:01:43 +01:00
bdistin
acd1740f0b docs: fix missing parameter type/description from #2193 (#2396)
* docs: Fix missing parameter type/description from #2193

* requested changes
2018-03-15 06:52:23 +01:00
Amish Shah
ef8366d189 voice: properly null-check udp socket first (#2317) 2018-03-13 09:48:18 +00:00
Pascal
513dbf2f68 fix(MessageReaction): do not increment count twice for own user
Fixes #2389
2018-03-10 14:11:33 +01:00
Pascal
0f7ce3f720 fix(GuildemojiStore): allow resolving of external ReactionEmoji 2018-03-10 14:08:59 +01:00
bdistin
630009f3cf fix: Convert lastMessage to getters (#2384)
* convert lastMessage to getters

* fix bug in pr

* requested changes
2018-03-08 10:19:43 -06:00
bdistin
799eea957e consistency: getters return null instead of undefined (#2385) 2018-03-08 10:15:06 -06:00
Lewdcario
a68f14500d fix: GuildMemberStore: unban returns user
fixes #2388
2018-03-08 10:08:59 -06:00
Pascal
85413481ed fix(DataResolver): always resolve with buffer when resolving urls
Fixes: #2379
2018-03-06 21:48:34 +01:00
Amish Shah
79b02dd35f voice: resolve "cb is not a function" error (#2317) 2018-03-06 10:36:05 +00:00
Amish Shah
8289b70e2c voice: resolve issue where dispatcher tried to send packets to null socket (#2317) 2018-03-06 10:21:44 +00:00
Amish Shah
835bff74cd lint: remove unused import 2018-03-05 20:17:38 +00:00
Amish Shah
ff825cd8b8 voice: fix #2331 (speaking not set back to false on stream ending) 2018-03-05 19:41:35 +00:00
Amish Shah
399d179ebc Merge branch 'master' of https://github.com/hydrabolt/discord.js 2018-03-05 19:30:21 +00:00
Amish Shah
e263063ba6 voice: update prism and fix framesize to work for opusscript 2018-03-05 19:30:18 +00:00
Pascal
3e6c3107c2 fix(GuildMemberRoleStore): make remove role remove roles again 2018-03-05 14:50:59 +01:00
Pascal
3f6a0e4de1 fix(GuildMemberRoleStore): only update roles after successful request
Fixes #2381
2018-03-05 11:32:03 +01:00
Jonah Snider
8b679913a4 docs: Change 'the this' to this (typo) (#2377) 2018-03-04 08:16:12 +00:00
Isabella
0a951cfc0f docs: TextChannel Webhooks fix&improvement 2018-03-03 18:55:54 -06:00
Isabella
b637c9c220 feat: allow multiple permission overwrites when editing channel (#2370)
* feat: allow multiple permission overwrites when editing channel

* undo Permissions#resolve change
2018-03-03 11:18:58 -06:00
Pascal
ca054affc7 chore: update typings submodule 2018-03-03 12:00:05 +01:00
Frangu Vlad
069dccfa3b docs: document the messages property for all TextBasedChannels (#2373)
* Document TextChannel#messages

* Same for DMChannels

* And GroupDMChannels
2018-03-03 11:04:33 +01:00
Will Nelson
cf7dcba1a5 Add toJSON methods (#1859)
* tojson things

* fix client

* ignore private properties

* remove extra property descriptors

* handle primitive flattening

* remove unused import

* add toJSON to collections

* reduce stateful props

* state

* allow custom prop names when flattening

* fix client

* fix build

* fix flatten docs

* remove guild.available, cleanup permissions, remove arbitrary id reduction

* fix util import

* add valueOf as needed, update member props

* fix incorrect merge

* update permissionoverwrites and permissions

remove serialization of permissions in PermissionOverwrites#toJSON.
change Permissions#toJSON to serialize permissions, by default excluding
admin checks.

* change Permissions#toJSON to return the primitive

* Permissions#toJSON explicitly return bitfield
2018-03-01 23:00:21 -06:00
Lewdcario
24571e465b docs: examples & improvements 2018-03-01 22:50:45 -06:00
Lewdcario
9b41a6a8a6 fix: re-add highest property to RoleStore and GuildMemberRoleStore
closes #2302
2018-03-01 11:52:29 -06:00
Will Nelson
2a9fdef9e5 add valueOf method to permissions (#2363) 2018-02-28 16:48:06 +01:00
Pascal
464fc14edd fix(Activity): ensure that timestamps are actually numbers
Fixes #2364
Discord sends those timestamps packed as SMALL_BIG_EXT, which get converted to strings in js.
~~Maybe they are already preparing their timestamps for 2038.~~
2018-02-28 09:31:42 +01:00
Frangu Vlad
9f8925226d docs(WIP): Bring the main doc pages up to date, and add more examples (#2094)
* Bring some docs up to date, as well as add a new example

* Missed an exclamation mark

* Do requested changes

* Do suggestions

* Same suggestions for the other examples

* Show people that they can also use reply with embeds

* Typos in embed.js example

* Remove object example from embeds, too complex
Suggested by Yukine

* Some changes, some requested changes

* Add moderation examples!

* Add attachment examples

* Missing dot

* Fix spacing

* Requested Changes

* Quote consistency

* Tfw you break the syntax
2018-02-27 20:04:53 -06:00
rei2hu
35babc706d Fix: discord sort method (#2355) 2018-02-23 21:18:42 -06:00
nekobako
c25ea45866 fix(StreamDispatcher): emit volumeChange event when the volume changes (#2349) 2018-02-21 22:21:13 +01:00
Sanctuary
dc6bce1f82 docs: Add links for the guide (#2346) 2018-02-21 09:44:11 +01:00
Ecstabis
3a3ca96b0d Added 2 basic role colors PINKISH_PURPLE and DARK_PINKISH_PURPLE (#2303)
* Added 2 basic role colors PINKISH_PURPLE and DARK_PINKISH_PURPLE

* Added documentation for added Colors PINKISH_PURPLE and DARK_PINKISH_PURPLE

* fix colour names

* docs
2018-02-20 16:51:03 -06:00
Pascal
05c5bdc476 fix(StreamDispatcher): do nothing when resume is called when not paused
Fixes #2324
2018-02-19 18:17:51 +01:00
Pascal
77dc3aafaa chore: update typings submodule 2018-02-19 16:11:49 +01:00
Kyra
a8172951d3 perf(Collection): Performance improvements (#2342)
* Update Collection.js

* ESLint
2018-02-16 10:19:30 +01:00
iCrawl
e6dfa38c85 chore: update typings(?) 2018-02-16 10:07:59 +01:00
iCrawl
5583e70eb6 fix: properly fix minified builds 2018-02-16 09:55:30 +01:00
iCrawl
1b9af41fbb chore: update test 2018-02-16 09:55:22 +01:00
iCrawl
0c285e784f Merge branch 'devsnek-refactor/webpacks' 2018-02-16 09:52:27 +01:00
Crawl
d720ad6334 Merge branch 'master' into refactor/webpacks 2018-02-16 09:48:54 +01:00
iCrawl
8e60743c0b fix: dont require snekfetch supplemental because they are not a thing anymore 2018-02-16 08:54:49 +01:00
iCrawl
332558a3d8 fix: npm scripts 2018-02-16 08:46:31 +01:00
iCrawl
672f93f5bd chore: bump deps and remove unneeded ones 2018-02-16 08:43:46 +01:00
Pascal
5cf8a634f8 chore: update typings submodule 2018-02-13 17:54:52 +01:00
Pascal
2fd4c6def7 chore(deps): update uws to 9.14.0
Closes #2327
2018-02-13 17:40:43 +01:00
SpaceEEC
47bc0fc51e feat(GuildChannel): add fetchInvites method (#2339)
* feat(GuildChannel): add fetchInvites method

* fix: actually use the 'channels' endpoint
2018-02-13 17:29:42 +01:00
Isabella
66c0512de2 feat(ShardClientUtil#broadcastEval): allow promise resolve (#2328) 2018-02-07 11:07:59 -05:00
Sanctuary
87e5a45659 feat(ClientOptions): add support for setting an initial presence (#2320)
* docs/feat(WebsocketOptions): Parse ws options presence

Allow the `presence` property in `WebsocketOptions` to be used the same way
as `ClientUser#setPresence`.

* Move presence options to top level
2018-02-04 21:32:45 +01:00
Snazzah
43363172c2 docs: Add TypeDef for MessageActivity (#2321) 2018-02-04 20:44:13 +01:00
Frangu Vlad
e0cbf0bb60 feature: add GuildEmoji#fetchAuthor (#2315)
* Make the base code

* Fxi lint
2018-02-02 20:34:21 +01:00
Gus Caplan
bd1bf11ed0 spotify stuff (#2314) 2018-02-02 12:45:18 -06:00
Lewdcario
234648bd2a fix(ClientApplication): createAsset incorrectly resolving image and posting 2018-02-02 11:41:08 -06:00
SpaceEEC
016526486c enhancement(Activity): add toString method (#2313) 2018-02-01 18:41:05 -06:00
Lasse Niermann
31873eb3a5 docs(ClientUser): mark email field as user account only property (#2306)
* Store Mail - User Account Only

Added that info

* docs(ClientUser): mark email field as nullable
2018-02-01 20:29:20 +01:00
Pascal
32e2dd212e fix: add clone methods to GuildMember and GuildMemberRoleStore
Fixes #2312
This adds clone method to both classes to achieve the expected behaviour when cloning a GuildMember, also cloning their roles store
2018-01-31 21:04:15 +01:00
Isabella
9810bdbc5f fix(MessageEmbed): remove length checks (#2304)
* fix(MessageEmbed): remove length checks

* update error messages
2018-01-29 10:56:55 -06:00
Lewdcario
d46eec4da4 fix(resolveColor): not interpreting DEFAULT correctly 2018-01-28 22:34:50 -06:00
Lewdcario
2e0048add1 docs: doc changes 2018-01-27 23:41:25 -06:00
Lewdcario
d93d628f19 make Message#member a getter 2018-01-27 17:04:03 -06:00
Gus Caplan
711bcc7a7c Update webpack.config.js 2018-01-27 12:56:45 -06:00
Dim
10f98d8e57 use String#padStart for Role#hexColor (#2294) 2018-01-27 07:42:49 +01:00
Pascal
8c288b56a2 chore: update typings submodule 2018-01-26 09:25:30 +01:00
Lewdcario
bd154bdd9e fix: nullable activity 2018-01-25 02:06:28 -06:00
Alex
e58ff642f5 Make Util#splitMessage handle edge cases properly (#2212)
* Make Util#splitMessage handle edge cases properly

* Restart Travis

* Set maxLength to 2000 + small tweak
2018-01-24 23:41:50 -06:00
Faith
58d85282b4 Fix Destructuring Errors in Util (#2171)
* Fix Destructuring

* Fix another one
2018-01-24 17:37:41 -06:00
Lewdcario
7e0e457334 fix(ClientUser#setStatus): resetting activity
The method would pass in null if no activity was passed, so this takes the current client presence instead of deleting it.
2018-01-24 15:09:40 -06:00
Frangu Vlad
a832b56469 GuildEmoji: Move all role related functions to a separate store (#2271)
* Prepare to work on moving all role functions to a Store

And yes, this is *another* patch branch cause I messed up my master branch to hell

* Move all emoji role related functions to its own store
Tested everything and it works! (With a reload of the client)
Also had to change a value in DataStore#holds
holds.name for GuildEmojis would return the emoji name instead of the class name

* New Line

* Thanks JS for circular dependency!
Because we can't have nice things...

* Do space's request

* Fix equals

* Fix space's point.

Raw API data has the role property as an array of IDs
2018-01-24 20:47:20 +01:00
Dragon Fire
16b5de5d52 fix(Role) Update usages of highestRole#comparePositionTo to use GuildMemberRoleStore (#2289) 2018-01-24 13:34:11 +01:00
Pascal
048e147497 fix(RoleStore): create method is supposed to take an options object 2018-01-24 09:02:37 +01:00
FireController1847
92c9f8864c Specify that Client#uptime is "in milliseconds" (#2288) 2018-01-24 08:24:24 +01:00
Frangu Vlad
00172e6c7d refactor: Move member role-related functions to a special store (#2242)
* Ignore this I need a patch branch for Git

* Move all member role related stuff to a new DataStore
GuildMemberRoleStore is a new store that holds all member role related stuffs
Because its consistent!

* Minorest doc fix ever
To whoever did this object, they forgot a `{`

* Fix the spacing in the docs

* Resue the stores resolve rather than copy paste
Cause I'm dum and it overwrite resolve to the guild role stores resolve soo

* Fix some requests
- Removed the bs private functions
- Set the roles in the constructor

But, I need feedback. There is no way, that I saw, to make a member have roles whenever GuildMmber#_patch is called,
due to the roles being null on the guild. So the only way might be the for loop and getter.

* Fix an issue that I caused in #add
I was testing some other things, and changed that to test. Forgot to change it back

* Actually make the store generate just once when the member is created by first initializing the roles in the guild
Also replaces GuildMember#_roles with GuildMemberRoleStore#_roles
Tested all functions to make sure the expected result happens.

* I missed this from moving remove from GuildMember to GuildMemberRoleStore

* Fix RoleStore#create docs
For real this time

* Do all the requested changes
- Rename all `somethingRole` to `something` (hoistRole => hoist)
- Refactor add and remove to be cleaner and re-use set

* Fix a bug where the store would loose some roles due to null roles that can throw an error in the for loop after they've been deleted

* Remove the `role.id || role` part of the add and remove functions as Appel suggested

* Replace roles.resolve with roles.resolveID for GuildMemberRoleStore#remove

* Don't use Array.isArray in checks
Use instanceof instead

* Woops, I forgot to change this
Renamed colorRole to color

* The docs have dots, so we place the dots back
2018-01-24 08:12:58 +01:00
Pascal
5352e28700 chore: update typings submodule 2018-01-23 07:27:39 +01:00
Pascal
07c48a6845 fix: require discordjserror to throw meaningful errors where necessary 2018-01-22 20:23:36 +01:00
Amish Shah
86da7af4f1 Update prism dependency 2018-01-21 17:47:26 +00:00
Cat
8a2ace45d8 docs: fix VoiceBroadcast documentation (#2277) 2018-01-21 18:23:23 +01:00
Michel Nguyen
edc4e2b751 docs: fix streamdispatcher documentation (#2275)
* docs change

* fix streamdispatcher documentation

Signed-off-by: Michel Nguyen <modzongaming@gmail.com>

* fucks sake

Signed-off-by: Michel Nguyen <modzongaming@gmail.com>

* typings

Signed-off-by: Michel Nguyen <modzongaming@gmail.com>

* typings again 👀

Signed-off-by: Michel Nguyen <modzongaming@gmail.com>
2018-01-21 18:23:00 +01:00
Amish Shah
83de7c0d4c Fix error messages 2018-01-21 15:52:32 +00:00
Pascal
3300e39690 chore: update typings submodule 2018-01-21 13:12:31 +01:00
Amish Shah
76891a1e00 try fix 2018-01-21 10:34:14 +00:00
Amish Shah
aa09490724 whoops 2018-01-21 10:31:12 +00:00
Amish Shah
b2708a6fa8 Merge branch 'master' of https://github.com/hydrabolt/discord.js 2018-01-21 10:29:06 +00:00
Amish Shah
0e262ea8d7 More informative stream errors 2018-01-21 10:29:03 +00:00
Pascal
93e083da4f fix(Guild): memberCount not decrementing when an uncached member leaves
This leads to GuildMemberStore#_fetchMany to always reject
because it expects more member than possible.

Also no longer call the GuildMemberRemove handler locally
to not decrement twice.
2018-01-21 07:30:59 +01:00
Kyra
986e6da196 Fix(GuildChannel#clone) options.parent not accepting (falsy) null. (#2262)
* Fixed (falsy) options not being set correctly

* Requested changes.

As a side note, I also default `options.withPermissions` for simplicity, and because it gets ignored in [`GuildChannelStore#create()`](https://discord.js.org/#/docs/main/master/class/GuildChannelStore?scrollTo=create).

* Fixed the overwrites option
2018-01-20 19:30:30 +01:00
Amish Shah
b16e6f8262 Fix VoiceBroadcast#play documentation 2018-01-20 16:57:27 +00:00
Amish Shah
f728d2be69 Update voice docs 2018-01-20 16:31:34 +00:00
Amish Shah
ac65ea41b4 Update voice docs 2018-01-20 16:26:44 +00:00
Amish Shah
f588b3fd20 Merge branch 'master' into voice-rewrite 2018-01-20 13:50:34 +00:00
Amish Shah
c63bdb5fb1 Remove redundant doc tag descriptions 2018-01-20 13:47:35 +00:00
Amish Shah
ca96e1478a Make docs technically correct 2018-01-20 13:45:22 +00:00
Amish Shah
791740220e Improve docs, allow for webm/opus demuxing and playing broadcasts without specifying a type 2018-01-20 13:01:48 +00:00
Amish Shah
f14193b93a Document examples 2018-01-20 12:48:28 +00:00
Pascal
fbd25f8677 fix(GuildMember): make edit method only modify a copy of the voice state
This is to fix stale members in voice channels.
2018-01-20 12:44:27 +01:00
Pascal
a22b856494 fix(WebSocketConnection): make errors in event handlers throw again
The error from something like client.on('ready', () => undefined.f);
would just be emitted as debug event instead of being thrown.

Simply moving the emitting part out of the try catch again solves this.
2018-01-20 09:05:07 +01:00
Yukine
bf0a68dbac Mark DataStores as public to directly display them in the docs. (#2268)
* make EmojiStore not Private anymore.

because why have something private if there is priority functionality on that class? also that causes that the docs wont show it directly

* make GuildChannelStore not private anymore

because why have something private if there is priority functionality on that class? also that causes that the docs wont show it directly

* make RoleStore not private anymore

because why have something private if there is priority functionality on that class? also that causes that the docs wont show it directly

* make ReactionStore not private anymore

because why have something private if there is priority functionality on that class? also that causes that the docs wont show it directly

* make all non private to stay consistent

* fix merge conflicts because of other PRs.
2018-01-20 08:00:44 +01:00
Amish Shah
ef02bd2935 Add stubs for docs 2018-01-20 00:05:37 +00:00
Amish Shah
2b5fc77a67 Rudimentary support for unified audio playing! 🎉 2018-01-19 23:55:59 +00:00
Amish Shah
8e5e1ad8fe Document Receiver 2018-01-19 23:03:01 +00:00
Amish Shah
c57c2889b7 Fix import errors for networking classes 2018-01-19 22:54:54 +00:00
Amish Shah
066fbfe330 Move voice UDP client and Websocket client to networking folder 2018-01-19 22:53:55 +00:00
Amish Shah
60c5c1486b Remove dead files 2018-01-19 22:51:53 +00:00
Amish Shah
c6c9c0918a Fix PacketHandler runtime error (EventEmitter not imported) 2018-01-19 22:51:26 +00:00
Amish Shah
cb161a8a40 Implement Receiver debug events 2018-01-19 22:47:01 +00:00
Amish Shah
83140f11b7 Fix ESLint and inline the voice readable stream 2018-01-19 22:41:31 +00:00
Amish Shah
dd618584d0 Simplify VolumeInterface constructor 2018-01-19 22:38:39 +00:00
Amish Shah
4a1b55d145 Receiver#createStream should take options 2018-01-19 22:38:10 +00:00
Amish Shah
2c1a302eea Redesign voice receiving, still needs cleaning up 2018-01-19 21:14:03 +00:00
Amish Shah
6058ea4888 Start voice receive rewrite 2018-01-19 17:45:37 +00:00
Amish Shah
580bda46ea Fix documentation for VoiceBroadcast (play methods return BroadcastDispatcher not StreamDispatcher) 2018-01-19 14:40:58 +00:00
Amish Shah
3b1c5d3494 Expose VoiceBroadcast#dispatcher so that the broadcast can be controlled 2018-01-19 14:39:51 +00:00
Amish Shah
e7375aa0fd Reimplement broadcast (un)subscribe events 2018-01-19 14:32:51 +00:00
Amish Shah
3d3c436e92 Merge branch 'master' into voice-rewrite 2018-01-19 14:06:41 +00:00
Schuyler Cebulskie
e9bdd3ad7e Tweak readme and docs welcome page 2018-01-18 19:59:21 -05:00
Schuyler Cebulskie
f649610c26 Merge branch 'master' into voice-rewrite 2018-01-18 19:49:23 -05:00
Schuyler Cebulskie
95d35a9efa Update typings submodule URL 2018-01-18 19:48:43 -05:00
Schuyler Cebulskie
16a910c988 Update repository references 2018-01-18 14:46:35 -05:00
Amish Shah
c522b65adb Point discord.js-docgen dependency to its new location 2018-01-18 17:54:45 +00:00
SpaceEEC
aa3407f705 Base Emoji class for ReactionEmoji and renamed GuildEmoji classes (#2230)
* feat: create base Emoji class for ReactionEmoji and new GuildEmoji

* rename EmojiStore to GuildEmojiStore to account for the new class' name
2018-01-18 02:38:45 -06:00
bdistin
b846cbd2b3 GuildChannel.permissionsFor(role) (#2254)
* GuildChannel.permissionsFor(role)

* 1Comp's requested changes
2018-01-18 02:28:14 -06:00
John Leuenhagen
d5b0cf9ffb Permissions improvements (#2126)
* add Permissions.toArray()

* accept Permissions objects to Permissions.missing()

* accept Permissions as parameter to Permissions.has()

* style fixes

* remove redundant line, update JSDoc for Permission.resolve()

* JSDoc, style, and checkAdmin fixes

* add Permissions.resolveToObject()

* accept PermissionResolvable to Permissions.missing()

* remove `resolveToObject`, fix constructor JSDoc

* remove redundant parameter type

* fix `Permissions.missing()`

* fix checkAdmin

* update Permissions.toArray() description

* eliminate ambiguity in Permissions.toArray() description

* add backticks to permission example

* remove irrelevant type in Permission ctor description

* use this.constructor to properly support OOP

* use simplified approach for Permissions.toArray()

* fix return type on Permissions.toArray()

* move `Permissions#toArray` to more suitable position

* bitwise approach to `Permissions#missing`

* allow `Permissions` to be iterated over

* don't checkAdmin on return array

* remove unnecessary conditional

* fix JSDoc indentation

* use simpler & more reliable approach for missing()

* update PermissionResolvable typedef
2018-01-18 02:17:50 -06:00
Artful
1db0906483 Client method examples. (#2264)
* Client method examples.

* Consistency

* As per hydras request 🙇

* Thanks kya
2018-01-18 07:47:05 +01:00
Michel Nguyen
19591b0bb1 docs: fix attachFiles() docs (#2267)
* docs change

* fix attachFiles docs

* why was this still here
2018-01-18 07:42:05 +01:00
Pascal
c125cc9c10 update typings 2018-01-17 17:20:45 +01:00
Amish Shah
b94d60d2ab Merge branch 'master' into voice-rewrite 2018-01-16 17:24:07 +00:00
Alex
e576387fea Fix ReactionCollector#remove and make Collector interface more consistent (#2221)
* Fix ReactionCollector#remove and make Collector interface more consistent

* Move those below the doc

* Remove object spread

* Only emit event arguments

* Forgot to delete this line

* Update docs

* Also fix this

* More edits to docs

* Snowflake|string
2018-01-16 01:33:58 +01:00
Isabella
36555c1cea refactor(GuildMember#manageable): refactored kickable and bannable (#2211)
* refactor(GuildMember#manageable): merged kickable and bannable code

* hydar suggestion
2018-01-16 01:32:40 +01:00
bdistin
4122db0275 Return undefined from Collection.find() / findKey() (#2260)
To be compliant with Array.find() / findIndex()
2018-01-16 01:24:19 +01:00
bdistin
3d32dea5e1 remove pointless function from GuildEmojisUpdate (#2256) 2018-01-16 01:20:51 +01:00
bdistin
3038d4b2c7 Address missing application docs in setPresence (#2257)
fixes #2103 according to how crawl says it should be fixed in #2104
2018-01-16 01:20:36 +01:00
bdistin
4fb7e64a39 Add parent, nsfw, bitrate, and userLimit options to GuildChannel.clone() (#2259)
* Add parent, nsfw, bitrate, and userLimit options to GuildChannel.clone()

* fix lint
2018-01-16 01:20:09 +01:00
iCrawl
f61b57ce10 Merge branch 'master' into voice-rewrite 2018-01-15 04:45:48 +01:00
pedall
42c0e50c92 Fix ShardClientUtil#broadcastEval - now really accepting functions (#2248)
* small fix to broadcastEval accepting functions

* dont ignore idea anymore (separate PR then)
2018-01-14 20:46:08 +01:00
Dim
351f5f7209 fix: missing height & width in embeds (#2249) 2018-01-14 13:28:46 +00:00
Dim
a3be0f3726 docs: Collection > RoleStore (#2251) 2018-01-14 13:28:00 +00:00
Amish Shah
83640a2640 refactor: tidier overflow checking in StreamDispatcher 2018-01-13 20:50:24 +00:00
Amish Shah
aaa318e465 Merge branch 'master' into voice-rewrite 2018-01-13 20:44:36 +00:00
Yukine
352bd13e6f fix typo in Error constants (#2243)
* fix typo in Error constants

* another one (#1)
2018-01-13 12:52:25 +00:00
Jisagi
ea028ae074 Fix destructuring errors in GuildChannelStore and RoleStore (#2244)
* Permissions#resolve fix

* Travis failed because >120 chars per line

* better fix

Permissions#resolve reverted
removed destructuring in GuildChannelStore and RoleStore
2018-01-13 12:51:09 +00:00
Amish Shah
d541cac9b3 Merge branch 'master' into voice-rewrite 2018-01-13 12:47:56 +00:00
Amish Shah
8cab673fea fix: stream dispatcher throwing key error due to missing secretKey 2018-01-13 12:47:19 +00:00
Gus Caplan
8aafcd6cde allow passing a function to shard eval (#2193) 2018-01-12 14:05:27 +01:00
bdistin
2249da464f Fix member.ban() and channel.clone() (#2241)
* Fix member.ban()

* also fix channel.clone()

* type is an option parameter in the new create

* lint

* better fix for clone
2018-01-11 18:44:35 +00:00
Isabella
9eac19d9d8 refactor: more oop with stores (#2216)
* refactor: more oop with stores

* forgot bulk delete

* Revert "forgot bulk delete"

This reverts commit 1b4fb999ee07b358ee6e1af9efb8981b84f83af1.

* appease linter

* missed some


shh

* fail
2018-01-11 16:33:30 +00:00
Amish Shah
d96f5f246d Merge branch 'master' into voice-rewrite 2018-01-11 16:16:43 +00:00
Amish Shah
90fc161159 Update copyright notice on license 2018-01-11 16:14:54 +00:00
Schuyler Cebulskie
da32dae8f5 Merge branch 'master' into voice-rewrite 2018-01-10 00:14:29 -05:00
bdistin
5efddac025 Fix Channel.delete() example (#2238) 2018-01-09 21:17:08 +01:00
Schuyler Cebulskie
e792757e32 Only create ShardClientUtil when spawned by ShardingManager 2018-01-08 22:13:46 -05:00
Amish Shah
096124b179 Merge branch 'master' into voice-rewrite 2018-01-05 21:24:23 +00:00
Amish Shah
eb40a663dd god damn it i forgot to save the file the first time 2018-01-05 21:23:21 +00:00
Amish Shah
eeded90782 Fix: "value" argument is out of bounds when writing timestamp header to packet 2018-01-05 21:22:11 +00:00
SpaceEEC
2318812f7f fix: allow the Util#parseEmoji regex to match emoji identifier (#2229) 2018-01-04 20:29:32 +01:00
Alex
780a311c0a Minor refactor to Util methods (#2213)
* Minor refactor to Util methods

* Fix derp
2018-01-04 01:18:56 +01:00
1Computer1
01f1f1b58e Fix query string on requests after ratelimited (#2215)
* Fix querystring being appended multiple times when ratelimited

* Better way?

* Better better way

* Fix empty queries
2018-01-04 01:17:15 +01:00
Isabella
45127bb408 docs: improve examples (master branch) (#2209)
* docs: improve examples

* more improvements


fix


maybe this


another example


collectors

* stuff
2018-01-04 01:12:05 +01:00
Isabella
61da73fee0 GuildMember#permissionsFor takes object (#2210) 2018-01-04 01:04:19 +01:00
Gus Caplan
abb93c9eb9 fix location of toString for channels (#2202) 2018-01-04 01:01:39 +01:00
Darqam
954a1c8d1a updating channelCreate example to reflect recent changes (#2194)
* updating channelCreate example to reflect recent changes

Type is now part of the options object, so the example should reflect that.

* changing type to reason per comment
2018-01-04 01:00:39 +01:00
Amish Shah
ac7e066126 Merge branch 'master' into voice-rewrite 2018-01-03 11:28:59 +00:00
Steven
229eb2be2d Fix Collector bug where checkEnd is only called on a valid message (#2186) 2017-12-31 20:21:29 +01:00
Gus Caplan
84e4dd6a99 animated emojis (#2182) 2017-12-31 20:20:52 +01:00
Alex
59d5c5a947 Don't send files in edit request (#2199) 2017-12-31 20:19:05 +01:00
Isabella
4063a3a16b fix(Guild#createChannel): default type to 'text' (#2184)
* fix(Guild#createChannel): default type to 'text'

* gus suggestion
2017-12-23 12:29:42 +01:00
Isabella
4f8f2087c1 docs/fix(setParent): docs update and nullable channel param (#2160)
* fix(setParent): no longer in GuildChannel

* refactored

* little bit less ugly

* space/appel suggestion

* docs fix

* shhhhhhhh

* fun docs trip

* prototype thing

* mark nullable
2017-12-21 09:31:17 +01:00
Yukine
0c16859746 enchanced docs for GuildChannel (#2155)
* enchanced docs for GuildChannel

* changes due request
2017-12-21 09:30:32 +01:00
Isabella
1598efa0b8 fix(CreateMessage): reassigning wrong content (#2169) 2017-12-12 06:33:10 +01:00
bdistin
fe9ea02f8b Make all VoiceChannel bitrates in bps (#2165)
* Make all VoiceChannel bitrates in bps

instead of mixed kbps/bps

* fix edit method in GuildChannel too
2017-12-12 05:02:53 +01:00
Isabella
443961ce43 fix(CreateMessage): fix attachment and array sending (#2158) 2017-12-10 21:22:59 +01:00
Schuyler Cebulskie
96971c432d Merge master into voice-rewrite 2017-12-02 19:48:43 -05:00
Schuyler Cebulskie
20689a51a1 Add exports for new util functions 2017-12-02 17:02:17 -05:00
Gus Caplan
4f4f0764e6 Merge branch 'master' into refactor/webpacks 2017-12-02 15:11:44 -06:00
bdistin
3e3674b1af Fix channels.resolve (#2137) 2017-11-30 14:39:58 -05:00
Yukine
134ef7a61b added a new Typedef for Bans you can get from <Guild>.fetchBans() and fixed a little typo in the fetchAuditLogs() method (#2108)
* added a new Typedef for Bans you can get from <Guild>.fetchBans() due recent change aswell as fixed a little typo in the fetchAuditLogs() mehtod so .type has no the correct type defined

* little change due request

* fixed indentation

* Update Guild.js

* Update Guild.js
2017-11-29 23:36:03 -05:00
Schuyler Cebulskie
77fc046550 Merge branch 'custom-structures' 2017-11-29 23:27:43 -05:00
Frangu Vlad
efd1c4c516 docs: Remove leftover docstring from 11.2 (#2115)
* Fix leftover docstring from 11.2

* Here too

* Update Guild.js

* Update GuildMember.js
2017-11-26 10:59:21 +01:00
1Computer1
2f84d95077 Add more options to MessageMentions#has (#2131)
* Add more options to MessageMentions#has

* Rename ignoreSelf to ignoreDirect
2017-11-26 10:58:17 +01:00
Schuyler Cebulskie
be02875f05 I don't even 2017-11-24 23:16:21 -05:00
Schuyler Cebulskie
7cd0a9525d Fix ClientUser not extending custom User 2017-11-24 23:05:00 -05:00
bdistin
dcf48e2225 Fix inconsistency with Channel Creation: CustomStructures (#2121)
* Fix inconsistancy with Channel Creation

* Because static get is a function, it thinks we are create a new instance based on that function, rather than the returned class...
2017-11-24 22:42:02 -05:00
Schuyler Cebulskie
950e65c7f1 Merge branch 'shard-overhaul' 2017-11-24 22:36:34 -05:00
Schuyler Cebulskie
0d188c0fba Rename ShardingManager#launch event to shardCreate 2017-11-24 22:33:29 -05:00
Schuyler Cebulskie
c6244ee6e1 Fix shards not respawning on exit 2017-11-20 22:37:35 -05:00
Schuyler Cebulskie
527c729aca Possibly fix weird behaviour 2017-11-20 22:29:46 -05:00
Schuyler Cebulskie
c447abad60 Clear evals and fetches on process death 2017-11-20 22:26:14 -05:00
Schuyler Cebulskie
b5459a96fa Move ShardingManager#message event to Shard#message 2017-11-20 22:20:32 -05:00
Gus Caplan
aaa92c0b05 fix things (#2116) 2017-11-20 12:57:45 +01:00
Schuyler Cebulskie
f3817e328b JK, back to Structures.extend 2017-11-20 01:37:19 -05:00
Schuyler Cebulskie
cf07b7e342 Re-add docs 2017-11-20 01:13:36 -05:00
Schuyler Cebulskie
1e0ee2f8fa Replace Structures.extend with set 2017-11-20 01:11:19 -05:00
Schuyler Cebulskie
a2a4c3c196 Fix Presence structure 2017-11-20 00:26:57 -05:00
Schuyler Cebulskie
3728c71867 Fix missing space 2017-11-20 00:24:43 -05:00
Schuyler Cebulskie
63b0c8d5cc Fix circular dependency 2017-11-20 00:23:41 -05:00
Schuyler Cebulskie
f004e6ccca Reimplement Structures.get 2017-11-19 23:00:56 -05:00
Schuyler Cebulskie
6d53d893a8 Make Structures.extend static and tweak error messages 2017-11-19 22:46:38 -05:00
Schuyler Cebulskie
47dc8fd046 Overhaul the way structures are extended 2017-11-19 22:41:45 -05:00
Schuyler Cebulskie
dc379519d3 Fix reaction structure name 2017-11-19 22:30:37 -05:00
Schuyler Cebulskie
0291fe41d8 Fix structure paths 2017-11-19 22:09:43 -05:00
Schuyler Cebulskie
f13c6d0768 Add ID to logo in welcome 2017-11-19 21:28:05 -05:00
Schuyler Cebulskie
c29804e3f8 i aint do nuffin 2017-11-19 21:19:46 -05:00
Schuyler Cebulskie
cfa512c447 Make structures for data stores extensible 2017-11-19 21:16:14 -05:00
Schuyler Cebulskie
26b28813a8 Use a custom promisified setTimeout 2017-11-19 13:47:04 -05:00
Schuyler Cebulskie
acf82f32c3 Mark Shard#_exitListener as private 2017-11-19 02:31:06 -05:00
Schuyler Cebulskie
1338e9bd8e Update sharding docs some more 2017-11-19 02:30:20 -05:00
Schuyler Cebulskie
975da5f1a5 Rewrite sharding class descriptions and link Client 2017-11-19 02:21:29 -05:00
Schuyler Cebulskie
9cd097492c Update doc for ShardingManager#createShard id parameter 2017-11-19 02:06:38 -05:00
Schuyler Cebulskie
f777c19fbf Fix naming conflict with ShardingManager#respawn 2017-11-19 02:03:44 -05:00
Schuyler Cebulskie
637ea09532 Fix lint error 2017-11-19 01:56:51 -05:00
Schuyler Cebulskie
2a332d8d15 Add ShardClientUtil#respawnAll 2017-11-19 01:54:10 -05:00
Schuyler Cebulskie
a414e4884f Overhaul sharding 2017-11-19 01:28:46 -05:00
Schuyler Cebulskie
ad69e2ba4c Merge branch 'master' of https://github.com/hydrabolt/discord.js 2017-11-18 23:34:50 -05:00
Schuyler Cebulskie
f4ac06024e Improve ColorResolvable docs 2017-11-18 23:34:34 -05:00
Crawl
5703e01132 update typings 2017-11-19 05:25:26 +01:00
Schuyler Cebulskie
a2074e8f25 Bump deps 2017-11-18 21:08:06 -05:00
Schuyler Cebulskie
b859501b6f Document and clean up some garbage 2017-11-18 20:30:13 -05:00
Schuyler Cebulskie
c622143e39 Remove Node version check from deploy script 2017-11-18 17:54:50 -05:00
Schuyler Cebulskie
abd6156a90 Maybe fix Travis some more 2017-11-18 17:50:30 -05:00
Schuyler Cebulskie
127d87dca8 Hopefully remove unnecessary work from Travis tests 2017-11-18 17:45:06 -05:00
Schuyler Cebulskie
297ac4e4db Still mucking about with Travis 2017-11-18 17:33:54 -05:00
Schuyler Cebulskie
4a15ccab0f Maybe fix dumb Travis behaviour 2017-11-18 17:26:03 -05:00
Schuyler Cebulskie
547b9cc2f3 Only run Node 8 build for test stage 2017-11-18 17:23:18 -05:00
Schuyler Cebulskie
b7c4df5dc1 Fix trailing space 2017-11-18 17:19:34 -05:00
Schuyler Cebulskie
99a245ce4d Merge branch 'master' of https://github.com/hydrabolt/discord.js 2017-11-18 17:12:31 -05:00
Schuyler Cebulskie
0f4ca39fa3 Add Node 9 to Travis 2017-11-18 17:12:27 -05:00
Drahcirius
8237bc054c So long, long (#1994)
* refactor: remove long dep

* fix linter issue

* remove file extensions

* optimize methods
2017-11-17 14:37:07 +01:00
Frangu Vlad
0cd4a92fb8 docs: Fixed some missing docstrings or incorrect return types (#2093)
* Fix some missing doc strings
Mainly just readonly tags

* Return an error when guild#allowDMs is ran from a bot account, and fix some return types

* WebhookClient implements Webhook, doesn't extend it

* Fix Client#rateLimit docs not showing what it returns

Cause I wanted to handle this event only to see no return props 🤔

* Actually make Client#rateLimit show the right info

Its an object with all the info
2017-11-17 14:20:57 +01:00
SpaceEEC
6fa4fc532c fix(Shard): extend EventEmitter to be able to emit events (#2112) 2017-11-17 02:49:57 -05:00
Schuyler Cebulskie
196cf7652e Add Shard#ready property and related events 2017-11-16 22:49:38 -05:00
Will Nelson
09315ae9db emit ReactionCollector#remove on all unreactions (#2096)
* emit ReactionCollector#remove on all unreactions

this will emit an event when a user removes a collected reaction. this
is in addition to Collector#dispose, which will only fire when all users
have unreacted to the same emoji.

* emit only collected removals
2017-11-16 15:24:53 +01:00
Isabella
2d8e26c24c docs: add Guild#features type (#2105)
* docs: add Guild#features type

* fixed spacing

* make it a list, and add MORE_EMOJI
2017-11-16 15:24:27 +01:00
Isabella
5cd42695ae refactor(MessageReaction): ReactionUserStore (#2078)
* refactor(MessageReactions): fetchUsers() is now users.fetch()

made a lovely class for it and all
happify linter


stuff


i know how to code i swear


i lied

* bdistin suggestions

* space suggestions, rename store

* fix count

* documentation update
2017-11-14 08:11:44 +00:00
Yukine
62544905a0 enhanced setUserLimit to reset when passing null to stay consistent with other methods (#2083)
* added a new check to setUserLimit so it won't silently fail anymore if you put a wrong type in

* adapt spaces idea of converting null to 0

* this way it looks cleaner

* and i need to remove this

* need to do it that way because like Gus said null will not change anyhting

* space prooved me wrong and idk why ist working now
2017-11-10 01:30:13 +01:00
SpaceEEC
05a41b5ca4 fix(Split/Webhook): readd message chunk sending and fix webhook avatar/username (#2085) 2017-11-06 02:42:24 +01:00
SpaceEEC
21d09f338e fix(Guild): correctly resolve user in Guild#addMember (#2090) 2017-11-05 18:52:33 +01:00
Amish Shah
2531065bbd Fix loop and only emit error, not warn 2017-11-04 15:02:58 +00:00
Amish Shah
6a523ba96a Reimplement StreamDispatcher error and start event in docs, emit error instead of debug if there are listeners for errors 2017-11-03 20:01:51 +00:00
Amish Shah
8efafb6a43 StreamDispatcher documented as extending WritableStream, not stream.Writable 2017-10-31 19:50:02 +00:00
Amish Shah
995cd181c9 Fix setFEC bug and use bitrateEditable in setBitrate 2017-10-31 19:47:58 +00:00
Amish Shah
121a40bb4a Use passes and increase highWaterMark to 12 2017-10-31 19:43:58 +00:00
Amish Shah
fa7f391b3a Fix ECONNRESET (again) 2017-10-31 18:12:49 +00:00
Gus Caplan
f63861a334 fix prepublish script 2017-10-29 18:40:56 -05:00
Amish Shah
2e1a28a6ee Use destroy and end in apt places 2017-10-29 18:04:36 +00:00
Amish Shah
cf30b1ef08 Add @extends to some classes 2017-10-29 17:43:22 +00:00
Gus Caplan
29a81eab73 standardize message object creation (#1986)
* standardize message object creation so i don't flip out again

* fix stuff

* Update Message.js

* Update index.js

* Update SendMessage.js

* Update Message.js
2017-10-29 14:54:00 +01:00
SpaceEEC
94a4a068b9 fix(TextBasedChannel): return a promise in startTyping and clarify count parameter (#2047)
* fix(TextBasedChannel): return a promise in startTyping

This fixes #2040

Calling TextBasedChannel#startTyping now returns a promise.
This promise resolves when the bot stops typing (TextBasedChannel#stopTyping) or rejects when an error occurs.
Calling the method again returns the same promise as long the bot is still typing.

* move code into the promise' executor

* Clarify the purpose of the returned Promise

* inverse if and clarify count parameter
2017-10-29 14:53:34 +01:00
Amish Shah
1697b13f15 Update to master 2017-10-29 13:50:49 +00:00
Amish Shah
5cb757add6 Add highWaterMark 2017-10-29 13:48:07 +00:00
Amish Shah
5879cd7c8e Merge branch 'voice-rewrite' of https://github.com/hydrabolt/discord.js into voice-rewrite 2017-10-29 13:19:41 +00:00
Amish Shah
d4a9e5ec9c Fix ESLint and handle stream errors 2017-10-29 13:19:38 +00:00
Sanctuary
1a8e8c7a67 docs: Add/normalize .toString() docs on all classes (#2042)
* docs: Add/normalize .toString() examples on all classes

* docs: Remove exclamation point on ClientApplication#toString example

* docs: Normalize .toString() descriptions on all classes

* Use "returns" instead of "concatenates"
2017-10-28 19:06:26 +02:00
SpaceEEC
0101392334 Documentation improvements (#2069)
* docs: fix documentation in various places

All stores: resolveID returns a nullable Snowflake
GuildAuditLogs: ActionType also can be ALL
MessageEmbed: make files property show up in the docs
ClientApplication: resetSecret and resetToken return a promise
ClientManager: status is readonly
Guild: features is an array of strings and ban no longer accepts a number or string
Guild: ban method no longer accepts a string or number
GuildMember: ^
RichPresenceAssets: small and large Image are Snowflakes, also fixed parameter documentation for small and large image url method
WebhookMessageOptions: file property is no longer a thing

* docs: improve GuildAuditLogs documentation

Prefix types with AuditLog to avoid confusion
Document GuildAuditLogs' static Targets and Actions properties and add necessary typedefs
Use typdefs over primitives where possible.

* fix documentation for Guild#defaultRole
2017-10-28 19:04:03 +02:00
SpaceEEC
a62d1e954d fix(Presence): pass client and default to offline (#2071) 2017-10-28 19:03:27 +02:00
Gus Caplan
50ad66f513 clean up readme a bit (#2054)
* clean up readme a bit

* Update README.md
2017-10-28 19:02:12 +02:00
William Tran
88719f0f42 Typos in docs (#2055)
* Typo in Guild.createRole docs

Added missing semicolon in example code.

* consistent periods in docs
2017-10-28 19:01:17 +02:00
Gus Caplan
c495ea025a fix raw event (#2074) 2017-10-28 18:58:46 +02:00
bdistin
b255af0825 Fix user.bot (#2073)
* fix user.bot

* user.avatar is nullable (docs)
2017-10-28 18:58:27 +02:00
bdistin
cda408534a user.patch shouldn't try to touch the token (#2072) 2017-10-28 18:57:50 +02:00
SpaceEEC
cd3d3344e8 fix(GuildMember#hasPermission): pass correct parameters to Permissions#has (#2070)
Also removed deprecated parameter of the method itself.
2017-10-28 18:57:16 +02:00
SpaceEEC
0a05761b49 Add new exports and remove a deprecated one (#2068)
* add new exports and remove a deprecated one

* fix incorrect require path
2017-10-28 18:55:59 +02:00
Johnson Chen
291af7e845 Change recent to timestamp because DiscordAPIError (#2065)
are lovely arn't they?
2017-10-28 11:35:38 +02:00
Will Nelson
dbf4ef9a7c handle string ffmpeg input (#2064)
* handle string ffmpeg input

* rename stuff for new purpose

* file prefix isn't needed

* pass tests

* remove dumb spaces in dispatcher docs
2017-10-27 22:42:21 +01:00
Schuyler Cebulskie
0fc9459450 Add TextChannel#setNSFW method (#2050)
* Add TextChannel#setNSFW method

* Doesn't look like anything to me

* butts
2017-10-27 10:34:18 -04:00
Gus Caplan
cd54e9317f Time Difference in REST (#2057) 2017-10-27 14:36:53 +01:00
Amish Shah
8a87cbf404 Better broadcast stuff 2017-10-27 14:32:02 +01:00
Amish Shah
a8511ebfaf Fix player 2017-10-26 21:50:52 +01:00
Amish Shah
393130dedb things 2017-10-26 21:26:00 +01:00
Amish Shah
bdf8955098 "yeah we need voice broadcasts cause we make big big music bots" no stop 2017-10-26 21:00:53 +01:00
Gus Caplan
bc30fdd867 Fix Avatar URL generation bug (#2063) 2017-10-26 20:07:27 +01:00
Amish Shah
3696b4a810 Add ability to disable volume transform 2017-10-26 18:56:02 +01:00
Amish Shah
6490d1b911 FEC and PLP exposed 2017-10-26 18:36:04 +01:00
Amish Shah
cc4aa75a71 Fix closing bug 2017-10-26 18:22:43 +01:00
Amish Shah
387d96bd6b Add setPLP and setFEC 2017-10-26 18:22:18 +01:00
Amish Shah
45ef80b92f Fix docs 2017-10-26 18:05:45 +01:00
Amish Shah
eeed5f23e3 Move streams to StreamDispatcher
breaking: removed AudioPlayer#setBitrate
2017-10-26 17:53:10 +01:00
Amish Shah
a79c9ac11a add: StreamDispatcher#pausedTime 2017-10-26 17:11:03 +01:00
Amish Shah
116b4c3788 Rename unpause to resume 2017-10-26 16:47:59 +01:00
Amish Shah
c8a75e4c29 More volume docs 2017-10-26 16:44:21 +01:00
Amish Shah
b83e12634c Docs 2017-10-26 16:35:20 +01:00
Amish Shah
780e67d19f Volume!! 2017-10-26 16:30:55 +01:00
Amish Shah
863e38676f Add back setBitrate 2017-10-26 14:39:58 +01:00
Gus Caplan
23a0b97fbb fix script name 2017-10-26 08:29:26 -05:00
Amish Shah
f6959a848f Start some docs crap 2017-10-26 14:17:56 +01:00
Amish Shah
ac0cc9a009 Remove useless SecretKey class 2017-10-26 14:02:44 +01:00
Amish Shah
3e3e6f9af7 Actually fix ESlint this time 2017-10-26 13:45:36 +01:00
Amish Shah
8913096f73 Fix Travis by removing stuff for fun 👌👌 2017-10-26 13:42:21 +01:00
Amish Shah
53ca34cbde Don't need to continue count and pausedTime amongst dispatchers 2017-10-26 13:33:14 +01:00
Amish Shah
f5d10a5f76 Pause/Unpause 2017-10-26 13:32:38 +01:00
Amish Shah
79c10f7084 Fix resetting timestamps 2017-10-26 12:01:04 +01:00
Amish Shah
ca93c05eee Merge branch 'master' into voice-rewrite 2017-10-26 11:59:28 +01:00
SpaceEEC
cd08a3b5a4 refactor(Actions): remove obsolete user and guild member get actions (#2061)
The UserGetAction was never used.
The GuildMemberGetAction was only once used.
Easily replaced with a shorter and more comprehensible line. (Also consistent with the rest of the library)
2017-10-26 08:52:03 +01:00
Amish Shah
a76e4c064d Fix sequence and timestamp growing too large 2017-10-26 00:32:14 +01:00
Amish Shah
7f90d4ebc5 Better ending 2017-10-25 23:46:05 +01:00
Amish Shah
48452173ca probably would cause an error somewhere 2017-10-25 23:21:02 +01:00
Amish Shah
65673197d4 Start rewrite with new prism 2017-10-25 23:14:41 +01:00
Gus Caplan
f8f804da36 wew 2017-10-25 16:09:36 -05:00
Gus Caplan
0589b7d7f1 zlib stream compression (#2028) 2017-10-25 17:30:03 +01:00
Isabella
0277d1de78 fix(Client): login wasnt using env.token (#2060) 2017-10-25 17:29:36 +01:00
Gus Caplan
ee1d4c53f2 Add rateLimit event (#2019)
* add ratelimited event

* add some useful props

* death

* more death

* Update tester1000.js

* Update RequestHandler.js
2017-10-24 21:07:21 +01:00
Amish Shah
80595d9bec Stop ESLint whining 2017-10-22 22:04:29 +01:00
Amish Shah
3e460162ca Update prism-media dependency to 0.0.2 2017-10-22 22:00:14 +01:00
Amish Shah
07bacf2a7d Update opusscript dependency to 0.0.4 2017-10-22 22:00:04 +01:00
Amish Shah
96ce1b0945 Update libsodium-wrappers peer dep and fix support for the newest version 2017-10-22 21:59:30 +01:00
Amish Shah
0004e19eca Fix ESLint issue 2017-10-22 16:03:35 +01:00
Amish Shah
29d743a521 Fix #2018 (rapid joining/leaving of voice channel causes a crash) 2017-10-22 14:29:49 +01:00
SpaceEEC
356778b9d5 fix(MessageBulkDeleteAction): remove deleted messages from cache (#2046)
Fixes #2036
2017-10-22 14:51:44 +02:00
Gus Caplan
339bcfd325 clean up webpack/deploy stuff (#2044)
* fix stuff i think

* Update deploy.sh

* Update deploy.sh
2017-10-22 14:45:32 +02:00
Gus Caplan
296046dbc6 remove ua manager (#2015) 2017-10-19 07:11:07 +02:00
Frangu Vlad
37f5256a04 fix(GuildChannel|Role.edit) Editing with a position not being right (#2010)
* Fix GuildChannel.edit and Role.edit for positions

* Re-use Util.setPosition
And also make it even more compact! And it works! \o/
2017-10-19 07:10:39 +02:00
Évelyne Lachance
8d7e745ee8 Patch timestamp of 0 on guild join date (#2041)
The Discord API seems to send a timestamp of 0 for the joined_at on presence updates. This patch resolves this by ignoring timestamps of 0.
2017-10-19 07:07:18 +02:00
kitsuyui
6b249ba454 Fixes #2034 (#2035)
Cancelling: https://github.com/hydrabolt/discord.js/pull/1745/files#diff-31d1bb7c08f2176ba026497c2e8d9b3fR81
2017-10-19 07:06:12 +02:00
SpaceEEC
fa3eee8fd9 fix(GuildDelete): disconnect voice and cleanup GuildChannels (#2026) 2017-10-19 07:03:02 +02:00
Gus Caplan
69d84081d3 Update Guild.js (#2027) 2017-10-19 07:02:32 +02:00
SpaceEEC
d8850dbdd8 feature(Webhook): allow to edit the channel of webhooks (#2039) 2017-10-19 07:01:20 +02:00
SpaceEEC
68a30584db refactor: remove redundant Client#rest and obsolete RESTManager#destroy (#2022) 2017-10-11 02:29:50 +02:00
Gus Caplan
d8f6198a12 fix websocket ratelimits (#2014) 2017-10-09 02:40:54 +02:00
Gus Caplan
69dcfa0708 fix Client#login from other invalid things (#2013) 2017-10-09 02:39:52 +02:00
Robin B
97823bc376 Various documentation adjustments (#2001)
* docs(various): Add "at" to createdAt description

* docs(Client): Adjust to fit with guilds property

* docs(various): Adjust phrasing & fix typos

* docs(various): Clarifications

* docs(Permissions): fix numerus

* docs(DataStore): capitalize DataStore

* docs(various): Formatting changes

* docs(Presence): Expand RichPresenceAssets docs

* Add space
2017-10-07 01:56:17 +02:00
Isabella
8fbae13040 fix(GuildAuditLogs): incorrect webhook reference (#2004)
* fix(GuildAuditLogs): incorrect webhook reference

* i cant trust my linter anymore

* use changes object
2017-10-07 01:55:53 +02:00
Frangu Vlad
f178f9ba6c fix(setPosition): rawPosition never getting updated when setPosition was called (#2006)
* Fix setPosition issue

The rawPositions were never updated from using setPosition, now they are.

* Fix bubbling issue

Also, yes. It took me 8 hours to get back home. Deal with it :D

* Watch your copy paste
2017-10-07 01:55:30 +02:00
Frangu Vlad
3871662a95 fix(setSpeaking) Fix #2005 (#2007) 2017-10-07 01:55:16 +02:00
Isabella
b462a7b94f fix(Role): setPosition typo (#2003) 2017-10-03 21:12:38 +02:00
Gus Caplan
abe98f716b run builds for prs without commiting (#1997) 2017-10-03 12:02:15 +02:00
Jack Baron
b8c70e7935 Typo in Message.awaitReactions docs (#1999) 2017-10-03 12:01:48 +02:00
Frangu Vlad
743668a10d fix: setPosition taking wrong IDs and edit with position 0 breaking (#1989)
* Fix typo in setPosition

* Same typo in Role

* Fix edit with position breaking when the position was 0

* Eslint

* Revert code but fix the position issue
2017-10-02 15:54:18 +02:00
Frangu Vlad
fc43736447 docs: Change repo for erlpack (#1992)
* Update npm command for erlpack

* Here too
2017-10-02 15:54:00 +02:00
kyraNET
b8f17aa51c [Documentation] Added a warn in fetchMentions (#1991) 2017-10-01 18:16:56 +02:00
SpaceEEC
3c0d7b8105 enhancement/feature(bulkDelete): accept array of ids and handle case of 0 or 1 message(s) (#1980) 2017-10-01 11:58:13 +02:00
Yukine
d41675c080 Export DataStore from the Discord.js module (#1981) 2017-10-01 11:57:00 +02:00
SpaceEEC
cc8060c1bd fix/feature(createChannel): add support for more properties and fix overwrites optionals (#1983) 2017-09-28 07:55:28 +02:00
SpaceEEC
1537dd7be7 fix(MessageEmbed): don't send 'files' as part of the embed (#1982) 2017-09-26 19:17:27 +02:00
Gus Caplan
27ccad1f1c tinify webpacks (#1975)
* tinify webpack

* meme

* fix long version

* more changes

* even smoler

* fix up logic

* fix build

* undo changes to user agent manager because its not webpack'd anymore

* the heck

* fix stupid

* clean up browser rules

* typo
2017-09-26 07:18:12 +02:00
Gus Caplan
4d4d2f2db7 add agent support (#1973) 2017-09-25 20:46:19 +02:00
Dim
97dc85f491 Typo (#1969) 2017-09-25 20:41:50 +02:00
Gus Caplan
6ce9a8743f update browser stuff and browser eslint (#1938)
* Update browser.js

* Update .eslintrc.json

* Update package.json

* Update package.json

* stop doing manually what webpack can do for us

* Update .eslintrc.json

* Update package.json
2017-09-24 21:01:47 +01:00
Dragon Fire
82841c6ce1 Fix for a small hasPermission error (#1971) 2017-09-24 18:41:06 +02:00
bdistin
f89ec00b30 Missed a deprecated method removal (#1950)
And another that should be removed too.
2017-09-24 17:29:45 +02:00
bdistin
c2029a66e9 Rip, fixes a bug we didn't even know to look for... 1870 lives on. (#1931)
possibly fixes #1870
2017-09-24 17:24:58 +02:00
Frangu Vlad
26c978c465 docs: Small doc improvement for PermissionOverwrites (#1964)
Just so people know what the possible types are.
2017-09-24 17:23:41 +02:00
Gus Caplan
dca0bac444 fix typo in ws manager (#1966) 2017-09-23 19:13:30 +02:00
Frangu Vlad
eb591dafba docs: Fix some small typos or "missing" docs (#1943)
* Fix documentation for GuildAuditLogEntry.target

* Update documentation for CategoryChannel#children

* Add EntryTarget for audit logs

I've done this to "fulfill" devsneks request while also showing all the possible results for the target of an AuditLogEntry

* Oops Eslint

* Private timeout sets gets set by BaseClient not WebhookClient

* Fix the "Missing Docs" for Presence#activity

* Small doc inconsistency

Array<Number> instead of Array<number> for Activity

* Client#emojis is an EmojiStore not a Collection

* Document ClientPresenceStore

Just so its clickable through the wiki, nothing else is documented

* Small fix for BaseClient#setInterval

You don't wait before executing, you execute every X ms

* GuildChannelResolvable takes a GuildChannel/Snowflake

* Typo in UserResolvable

* Another typo for UserResolvable

* Add the number to the Status and VoiceStatus docs

Its probably not needed, but just so the user knows what each number means, its now documented.
2017-09-21 07:02:47 +02:00
Gus Caplan
f2502e29b9 update dep for org name change (#1953) 2017-09-20 21:03:00 +02:00
SpaceEEC
3ace61a179 fix(ClientManager): reject login with proper error on timeout or on connection failure (#1947) 2017-09-16 20:32:03 +02:00
SpaceEEC
ec4c98704f refactor: make use of destructuring for Constants (#1942) 2017-09-16 20:31:36 +02:00
SpaceEEC
25ece1882b fix(Reactions): make MessageRection#id again null for default emojis (#1940)
Which was causing issues when resolving their identifier and MessageRection#id was also stated as nullable Snowflake, which a unicode not is
2017-09-14 12:36:08 +02:00
Gus Caplan
b62c472d0a Fix .npmrc to not create package-lock.json (#1936) 2017-09-13 02:19:29 +02:00
bdistin
64cbb98fb3 Channel permissionLock support (syncing with category permissions) (#1924)
* add permissionsLocked

* wip permissionLock()

* should be good

* better method name

* see if this fixes channel jumping

* fix property names

* each overwrite is a different instance, and thus the pointers do not equal, even if the values do.

* add more documentation to the edit method
2017-09-11 19:33:30 +02:00
Raphael
18389c7659 fixed small typo's in the Docs and added an example to <Guild>.setSystemChannel() (#1934) 2017-09-11 19:33:04 +02:00
SpaceEEC
cc0b65d70b fix(EmojiStore): return super.create in the create method (#1932) 2017-09-11 01:20:55 +02:00
bdistin
29b4ca7f23 Fixes #1929 (#1930) 2017-09-10 18:13:28 +02:00
bdistin
98b81fac38 fix permissions not resolving correctly (#1928) 2017-09-10 16:27:04 +01:00
Frangu Vlad
3767b35189 Fix check for GuildChannel#deletable (#1925)
You can now delete any channel you want, even if its ID is the same as the guild ID
2017-09-10 14:25:33 +02:00
Robin B
fc1e78e545 fix(DataStore): make resolveID work properly (#1927) 2017-09-10 14:21:08 +02:00
Drahcirius
63f6247ce5 fix/feat(MessageEmbed): deep copy fields and fix files when passed into constructor (#1864) 2017-09-09 23:43:13 +02:00
Gus Caplan
c523e224d7 fix sorting things (#1922)
* fix sorting things

* Update Guild.js
2017-09-09 23:43:02 +02:00
Gus Caplan
f4c2d6dfa2 fix a thing (#1921) 2017-09-09 22:55:26 +02:00
Gus Caplan
2ffe3048ba clean up positions (#1919)
* clean up positions

* perf i guess
2017-09-09 22:40:32 +02:00
bdistin
98582cd1b7 Permissions Cleanup (#1643)
* fix Permissions.add/remove, by completely changing what they do

* permissions cleanup

Removes overwrite._denied and overwrite._allowed in favor of overwrite.denied.bitfield and overwrite.allowed.bitfield

uses the modified Permissions.add and Permissions.remove to clean up existing code

fixes GuildMember.missingPermissions

changes Permissions add/remove to reverse loops for speed, changes resolve to allow the number 0 as a valid permission.

* Revert createChannel overwrite.allow / overwrite.deny for arrays of {allow:bitfield, deny:bitfield}

Documentation should be improved here, although I would need advice. I believe a overwrite object typedef is needed, to show the structure of the object, and also include that collections may be used for this, rather than arrays.

* api router fix for overwritePermissions

* add Permissions.freeze, and change all returned Permissions to immutable instances

* Make Permissions a permission resolveable

change role.permissions to be an instance of Permissions

* Make permissions.add/remove return a new instance if the instance is frozen

* Fix invalid error

* Update GuildChannel.js

* Update Guild.js

* fix bad merge
2017-09-09 22:07:39 +02:00
bdistin
b3e5f6271c More docs stragglers I didn't see (DataStore cleanup) (#1912)
* travis can see more than I can

* Update PresenceStore.js

* should fix missing parent travis message
2017-09-09 20:20:19 +02:00
Frangu Vlad
5b46ae59bd Fix some documentation about the category channels (#1917)
* Document CategoryChannel

* More fixes

* Sorry Crawl

* createChannel can return CategoryChannel

* Did senks requests

* I can't grammar

* Other snek request
2017-09-09 20:18:41 +02:00
Gus Caplan
c46c092d0d add channel categories (#1727)
* add channel categories

* add specific class

* speed

* Update Channel.js

* fix type typo

* Update Channel.js

* rewrite position stuff in prep for category sorting

* fix small issues in generation of permissions

* Update Guild.js

* Update Constants.js

* Update GuildChannel.js

* doc fix

* Update GuildChannel.js

* <.<
2017-09-09 14:11:54 +02:00
bdistin
ac4b2b3193 Fix GuildMember being undefined (#1915)
* GuildMember being undefined

* tested... not even a circular.
2017-09-09 14:10:57 +02:00
Dragon Fire
30757cc97b Fix for emojis not being an EmojiStore (#1916)
* Fix for emojis

* Proper fix
2017-09-09 14:10:27 +02:00
Dragon Fire
4626bca76f Fix resolveID typo in guild.unban (#1913) 2017-09-09 01:45:03 +02:00
bdistin
4748577194 Fix DataStore cleanup docs (#1911)
* fix RoleStore Docs

* fix ChannelStore docs

* fix GuildChannelStore docs

* fix GuildStore docs

* fix MessageStore docs

* fix ReactionStore docs
2017-09-09 00:16:43 +02:00
Gus Caplan
67c239b33f update webhook cache and message cache stuff (#1910) 2017-09-08 23:19:30 +02:00
bdistin
dd085ceaee Datastore cleanup (#1892)
* Start Store cleanup

* wip store cleanup

* fix iterables initiating datastores

* handle the possibility of a datastore with no holds and no its own 'create' method

* more cleanup (instances that need more than just client/data)

* missed RoleStore extras

* not sure how eslint didn't catch that tab...

* avoid re-getting the channel we already have...

* cleanup resolvers and refactor them into DataStores

* ^

* and remove

* fix some bugs

* fix lint

* fix documentation maybe?

* formatting

* fix presences

* really fix presences this time

* bad fix was bad... let;s see how bad this one is..

* forgot to save a file

* make presence resolving take userresolveables too

* fix tabs in jsdocs

* fix bad fix from last night that caused issues, with better fix...

* oops
2017-09-08 23:06:10 +02:00
Isabella
0607720ec8 docs: improve documentation (#1898)
* improve channel documentation

* forgot some stuff

* another one

* im good at this

* i did a dum
2017-09-08 02:01:35 +02:00
Robin B
41c4999c2b fix(Guild): Fix setChannelPositions method (#1900) 2017-09-08 00:50:28 +02:00
SpaceEEC
e34bd7c09c fix(Errors): throw DiscordjsErrors where one would expect them (#1905) 2017-09-08 00:50:01 +02:00
Robin B
d6b276bc29 refactor(Attachment): Merge MessageAttachment with Attachment (#1894)
* refactor(Attachment): Merge MessageAttachment with Attachment

* refactor(Attachment): Rename setup to _patch for consistency

* refactor(MessageAttachment): Global rename of Attachment class
2017-09-06 23:12:20 +02:00
SpaceEEC
694f78cd43 fix(WebhookClient): use applyToClass instead of multiple inheritance (#1896) 2017-09-06 23:11:40 +02:00
iCrawl
2305311ec1 fix: voice websocket sending 2017-09-06 16:38:42 +02:00
Gus Caplan
675e1eccb1 Separate websocket internals for RPC (#1893)
* websocket centralization

* more centralization

* whoops

* Update WebSocket.js
2017-09-06 07:20:10 +01:00
Amish Shah
f95ae4fcb7 Fix userUpdate not triggering for initial setting (or removal) of avatars (#1849) 2017-09-05 19:44:59 +01:00
Amish Shah
99419a3670 Fix #1310 (strip RTP header extensions) 2017-09-05 19:14:54 +01:00
iCrawl
9e66e806ce fix: minified webpack builds 2017-09-05 19:03:06 +02:00
iCrawl
a8df63ad1a docs: collection first, firstKey, last, lastKey
"count is negative" -> "amount is negative"
2017-09-05 18:04:18 +02:00
Amish Shah
4a8ada9c43 Fix ESLint error 2017-09-05 12:02:21 +01:00
Amish Shah
e686c9a816 Fix userUpdate event 2017-09-05 11:52:17 +01:00
Robin B
e5ac8f34ee Collections: Negative amounts and fixes (#1889)
* feat(Collection): Negative amounts plus fixes and refactor

* fix(Collection): Fix result when supplying false boolean as amount
2017-09-05 11:31:33 +01:00
Amish Shah
37d84b14f8 Re-add VoiceChannel#members and messageUpdate to the documentation 2017-09-05 11:16:56 +01:00
SpaceEEC
87fa74acd4 ClientUserGuildSettings: avoid uncaught exception and a bit of refactoring (#1885)
* refactor(ClientUserGuildSettings): make client first parameter of the constructor

* refactor(ClientUserChannelOverride): patch if possible rather then reinstantiating every update

* fix(ClientUserGuildSettings): avoid uncaught exception when patching newly joined guilds/gdms
2017-09-05 02:40:46 +02:00
SpaceEEC
bb4fe256e0 fix(Client): apply shardId and shardCount to the correct options object (#1888) 2017-09-05 02:40:22 +02:00
Schuyler Cebulskie
70612d3a7c Update typings 2017-09-04 18:39:47 -04:00
Gus Caplan
18e3801bb7 lots of important stuff (#1883)
* lots of important stuff

* Update Constants.js
2017-09-04 17:49:44 +02:00
Cynthia Lin
3a503ef56e Fix code inconsistencies and redundancy in util/Collections.js. (#1884)
* Normalize undefined type checks in collections with typeof operators.

* Remove redundant number type checking in collections.

Number.isInteger() throws false for strings and any other types that aren't numbers.
2017-09-04 17:45:58 +02:00
Amish Shah
2e4de62ddf Potentially fix #1870? 2017-09-04 14:14:11 +01:00
Robin B
ea1949a0e2 fix(MessageStore): Fix fetchPinned method and add notice. (#1881) 2017-09-04 05:26:36 +02:00
SpaceEEC
f40a5e9f88 feature(MessageReaction): add after option when fetching users who reacted with an emoji (#1882) 2017-09-04 05:22:01 +02:00
SpaceEEC
c4b5736a16 refactor/fix(DataStores): move instantiating of store related classes into their date stores (#1869)
* refactor/fix(DataStores): move instantiating of store related classes into the relevant create methods and fixed FetchMemberOptions

* Renamed ChannelStore's constructor parameter for claritiy

* define client property before creating items from passed iterable to avoid the client property being undefined

* Fix fetching members with a limit

* add static Channel#create back and moved channel instantiating there

* make ChannelStore's constructor accept an iterable

* make iterable an optional parameter, allow to just pass client and options

* fixed a little typo in docs of <User>.displayAvatarURL() (#1872)

* Rewrite presence a little bit (#1853)

* such presence many good

* Update PresenceStore.js

* Update index.js

* Update ClientPresenceStore.js

* Update Presence.js

* Update ClientPresenceStore.js

* Update ClientUser.js

* Update Presence.js

* add timestamps and party

* Update Presence.js

* Update PresenceStore.js

* Update ClientPresenceStore.js

* Update ClientPresenceStore.js

* fix: made options.type optional in ClientUser#setActivity (#1875)

* fix: made options.type optional in ClientUser#setActivity

* some changes, smol fix

due to too many types being possible, it should just be defaulted to 0. this means streamers will have to set the type manually, though.
also mistake with activity.name check

* docs(Collection): Adjust exists documentation (#1876)

Since the return value of Collection#exists is basically just a boolean of Collection#find's result, the same documentation and arguments can and should be applied.

* refactor(Emoji): remove Guild#deleteEmoji in favour of Emoji#delete (#1877)

* refactor/fix(DataStores): move instantiating of store related classes into the relevant create methods and fixed FetchMemberOptions

* Renamed ChannelStore's constructor parameter for claritiy

* define client property before creating items from passed iterable to avoid the client property being undefined

* Fix fetching members with a limit

* add static Channel#create back and moved channel instantiating there

* make ChannelStore's constructor accept an iterable

* make iterable an optional parameter, allow to just pass client and options

* rebase, this time with saving the file

* address issue with falsy activity throwing errors when setting client's presence
2017-09-03 12:57:49 +02:00
SpaceEEC
c93c4ad21f refactor(Emoji): remove Guild#deleteEmoji in favour of Emoji#delete (#1877) 2017-09-03 12:01:47 +02:00
Robin B
efbde07650 docs(Collection): Adjust exists documentation (#1876)
Since the return value of Collection#exists is basically just a boolean of Collection#find's result, the same documentation and arguments can and should be applied.
2017-09-03 12:00:36 +02:00
Isabella
39013b1242 fix: made options.type optional in ClientUser#setActivity (#1875)
* fix: made options.type optional in ClientUser#setActivity

* some changes, smol fix

due to too many types being possible, it should just be defaulted to 0. this means streamers will have to set the type manually, though.
also mistake with activity.name check
2017-09-03 12:00:11 +02:00
Gus Caplan
c4df2502ec Rewrite presence a little bit (#1853)
* such presence many good

* Update PresenceStore.js

* Update index.js

* Update ClientPresenceStore.js

* Update Presence.js

* Update ClientPresenceStore.js

* Update ClientUser.js

* Update Presence.js

* add timestamps and party

* Update Presence.js

* Update PresenceStore.js

* Update ClientPresenceStore.js

* Update ClientPresenceStore.js
2017-09-02 23:57:02 +01:00
Raphael
765b652e6a fixed a little typo in docs of <User>.displayAvatarURL() (#1872) 2017-09-02 14:56:49 +02:00
SpaceEEC
1bdaa62481 fix(Guild): passing the constructor partial data from an invite no longer errors (#1868) 2017-09-01 16:05:02 +02:00
Isabella
b8a37b6f0c fix removal of Guild#afk/system channels and icon (#1863)
* fix removal of Guild#afk/system channels

* guild#setIcon too

* less ternary, many wow
2017-09-01 07:33:41 +02:00
Frangu Vlad
434a22dc4e MessageOptions can take content (#1861) 2017-08-31 18:27:58 +02:00
Amish Shah
7f921883f4 Fix TextChannel#createWebhook 2017-08-31 15:55:05 +01:00
Frangu Vlad
7b6190da01 Fix documentations that were incorrect or missing (#1837)
* Fix docs for Guild#pruneMembers

* ClientApplication returns

* Guild#deleteEmoji

* Guild#setRolePosition takes RoleResolvable

* Client#fetchApplication returns ClientApplication not Oauth2Application

* ClientDataResolver#resolveImage can return null

* ClientApplication#toString small example

* Guild#allowDMs now has a only for user accounts warning

* ClientUserSettings#patch is private and setGuildPosition has a user account warning

* Role#setPermissions can take PermissionResolvable, not just String

* ChannelCreationOverwrites is for a role or a member, not for a "group"

* Fix ChannelData#userlimit string being wrong
"The user limit of voice the channel" :lul:

* ChannelResolvable is only for Channel or Snowflake

* EmojiIdentifierResolvable supports Snowflakes

* UserResolvable doesn't take a guild

* Make patch functions private

* Remove examples

* Webhoox#edit options.name defaults to the webhook name

* Make VoiceConnection functions private

* Am dum
The whole ClientUserSettings category is only for self bots soo

* Value for update functions is *

* Make update functions be private

* Fix GuildEditData missing Ssytemchannel property

* PermissionOverwriteOptions can accept null as an option
(Why did no-one document this?)
2017-08-31 09:16:27 +02:00
Amish Shah
5121a02f13 Fix #1854 2017-08-30 12:33:01 +01:00
Amish Shah
eb5ba4e45e Fix #1855 2017-08-30 12:20:32 +01:00
SpaceEEC
4e028d713a Fixing MessageReaction#count always being 1 (#1857) 2017-08-30 13:01:27 +02:00
SpaceEEC
b7c55f02c2 Allow Message#edit to accept a MessageEmbed as options parameter (#1844) 2017-08-28 03:05:34 +02:00
SpaceEEC
65d9d46a3c Fixed DataStore, deprecation leftovers and a bit of Event Constants (#1841)
* Fixed leftover fetchThing and removed unused methods/error messages

* Added resume event constant and used event constants wherever possible

* Replaced mentions of removed method name with their new name.

* Fixed typo: resume -> resumed
2017-08-28 00:11:28 +02:00
SpaceEEC
c4fecf6609 Simplified image resolving and used an options object when creating webhooks (#1843) 2017-08-28 00:11:19 +02:00
SpaceEEC
258fc4ecf3 Fix MessageMentions#has not returning true for role mentions (#1840) 2017-08-27 23:51:15 +02:00
iCrawl
3c532f16bc Remove unused Util require 2017-08-26 16:12:18 +02:00
Amish Shah
4f5cbbc0f0 Merge branch 'master' of https://github.com/hydrabolt/discord.js 2017-08-26 13:51:56 +01:00
Amish Shah
7d750c4680 pass on error 2017-08-26 13:51:53 +01:00
Gus Caplan
d792c6764a ChannelStore LRU (#1832) 2017-08-26 13:48:31 +01:00
Amish Shah
92a52460e1 Fix GuildMemberStore docs 2017-08-26 13:47:26 +01:00
Amish Shah
30dd3e0cff Fix #1684 2017-08-26 13:43:13 +01:00
Amish Shah
51fe80fd11 fix fetching all members 2017-08-26 13:08:54 +01:00
Amish Shah
c3d7c73e47 Add GuildMemberStore#fetch 2017-08-26 13:00:36 +01:00
Frangu Vlad
284f4e8ac0 Fix MessageEmbed copy paste (#1834)
The addField function wouldn't have errored if value wasn't a string
2017-08-26 10:03:44 +01:00
BigBrainAFK
86ffdc38d3 Mark video property as readonly (#1833) 2017-08-26 10:00:33 +01:00
Amish Shah
5fcc483ded Donate badge thxxx 2017-08-26 00:26:03 +01:00
Amish Shah
170f687d81 actually fix that delete thing (#1507) 2017-08-26 00:08:12 +01:00
Amish Shah
5a3b59b4b0 Fix #1685 2017-08-25 23:57:29 +01:00
Amish Shah
84153be894 Fix #1281 2017-08-25 23:41:26 +01:00
Amish Shah
5f694d1149 Make resolve types stricter
- UserResolvable no longer allows a guild
- ChannelResolvable no longer allows a message or a guild
- ChannelResolvable no longer allows a message or a guild
2017-08-25 23:10:05 +01:00
Isabella
fbb1253b3f Added resolveImage to reduce code duplication (#1820)
* add client#resolveImage

* oops

* resolveFile fix

* async is the future

* async

* update doc example

* build fix

* doc fix

* fix docs

* thx hydar
2017-08-25 22:17:38 +02:00
Amish Shah
b8315b79c7 Store and Model Refactor (#1618)
* UserStore refactor

* Create ChannelStore, remove redundant methods in ClientDataManager

* Create GuildStore

* Emoji stuff

* Use a Base class where possible to reduce code duplication

* Remove unnecessary comments from ChannelStore

* Add Base._clone();

* Remove unused ClientDataManager methods

* Refactor some more stuff

* ESLint

* Move Client#fetchUser to client.users.fetch

* Remove .has checks and just see if .get is truthy

* Fix guild member chunk error

* ESLint

* Fix typo

* Fix channel storing for user bots

* Remove ClientDataManager

* GuildChannelStore

* Reduce use of Util.cloneObject

* and this one too

* update typings

* Fix MessageUpdate handling (#1507)

* Fix role updates (probably fixes #1525)

* fix for eslint

* Address some of appell's comments

* Use debug constant

* start message store crap if it's ugly tell me later k

* fix that

* message store but works™️

* clean up guild stuff

* clean up channel store stuff

* clean up channel event handling

* does this message stuff work? find out soon in the next episode of dIsCoRd.Js

* eslint

* emojis

* emojis and reactions

* hi my name is eslint and im A LIL SHIT

* so i forgot this huh

* user stuff

* Fix @class

* Fix message stuff

* Fix user store docs

* Document all the bases

* fix the super things

* tidy up remove

* fix textbasedchannel

* fix that too

* fix emoji store

* make voice state stuff less ugly

* make voice states even less ugly

* make members less bad

* fix bug

* fix that too

* fix reactions

* how was this broken for so long

* role store

* remove super._patch from UserConnection

* Rename UserProfile#setup to _patch

* remove unnecessary super calls

* update docgen dep (pls fix travis thx)

* doc messagestore

* fix docs

* message store docs

* things

* DOCS PLS

* more things

* Document TextBasedChannel#messages as a MessageStore

* Rebase

* All the stores!
2017-08-25 21:08:58 +01:00
iCrawl
243ff48a67 Remove unneeded doc string 2017-08-24 00:36:13 +02:00
Gus Caplan
b9ea83afb4 update web.md (#1821) 2017-08-22 21:20:26 +02:00
Gus Caplan
b055dae998 make webpack over 9000 times better (#1816)
* webpack stuff

* even better

* Update browser.js
2017-08-22 19:55:28 +02:00
Isabella
4520c801d3 update attachment & docs (#1815) 2017-08-21 23:11:58 +02:00
Isabella
0c0ec72cb8 Fix Guild#createRole with position (#1720)
* Fix Guild#createRole with position + validation

* remove position validation, small update

* fixed async issue if position provided
2017-08-20 23:36:22 +02:00
Will Nelson
2c763073d7 add capture groups to MessageMentions and validate snowflake ranges (#1612)
* add capture groups

* update patterns to valid snowflake ranges
2017-08-20 23:26:13 +02:00
bdistin
9c2e3b8978 Pass the collection of X collected in collectors (#1594)
...to the filter function.
2017-08-20 23:13:08 +02:00
Gus Caplan
8b8a365e99 fix ratelimits (#1806) 2017-08-20 10:14:38 +02:00
Gus Caplan
8c855855cd Guild/systemchannel (#1799)
* add cool system channel

* Update Guild.js

* Update Guild.js

* Update Guild.js
2017-08-20 05:15:02 +02:00
Gus Caplan
55543754b9 proper fix for #1685 (#1805)
* Update WebSocketConnection.js

* Update WebSocketConnection.js

* Update WebSocketConnection.js

* Update RESTManager.js
2017-08-20 05:14:49 +02:00
Gus Caplan
9b97fe292f Remove partial classes (#1794)
* remove partial objects

* remove partial evil

* Update Invite.js

* Update Invite.js
2017-08-17 20:49:41 +02:00
iCrawl
fff8b764af Update package.json 2017-08-17 20:20:20 +02:00
iCrawl
2aa2f73c74 Docs cleanup 2017-08-17 20:04:01 +02:00
Gus Caplan
5ce0def9d0 fix sync (#1792)
* Update Ready.js

* Update ClientDataManager.js
2017-08-17 18:28:01 +02:00
Gus Caplan
23d42d7e22 permissions rename :3 (#1788)
* permissions rename :3

* Update Permissions.js

* Update TextChannel.js

* Update GuildChannel.js
2017-08-17 18:27:50 +02:00
SpaceEEC
e677543c30 Allow to set the new game types via ClientUser#setPresence and ClientUser#setGame (#1782)
* Allow to set the new game types via ClientUser#setPresence and setGame

* Accept string version of types, fix options parameter, remove Presence#streaming

* One line if statement, don't reuse data.game when game is already reassigned and fix error message

* Removed redundant if statement
2017-08-17 18:27:32 +02:00
Gus Caplan
6065fe1f8c update image sizes, adding some more (#1781) 2017-08-15 21:55:07 +02:00
Gus Caplan
71f2cc10f1 add cover image (#1780)
* add cover image

* Update ClientApplication.js
2017-08-15 21:54:09 +02:00
Gus Caplan
57977b063e channel stuff (#1775)
* channel stuff

* abstract channel creation

* Update Channel.js

* Update Channel.js

* Update Channel.js

* Update Guild.js

* Update Constants.js

* e
2017-08-13 13:57:25 +02:00
SpaceEEC
b2c7fcb603 Add support for new game types (#1777) 2017-08-13 13:56:45 +02:00
Johnson Chen
9c52030c29 ClientUser Fixes (#1741)
* Fixes #1702

* Remove Comments

* Follow what Gus said... I hope

* JSDoc

* Update ClientUser.js

* TIL my knowledge about JSDocs was a lie
2017-08-12 12:01:43 +02:00
SpaceEEC
8034c0437d Fix VoiceChannel#setName and ChannelData#userLimit is a only voice thing (#1771) 2017-08-12 11:55:55 +02:00
Gus Caplan
fbdf028b86 :3 (#1774) 2017-08-12 10:58:51 +02:00
Gus Caplan
3ba224900f new application stuff very hype (#1764)
* application stuff, more to come

* docstrings

* Update Message.js
2017-08-11 19:09:06 +02:00
Gus Caplan
3c7869c1b7 update retry case for 5xx (#1765) 2017-08-10 20:31:45 +02:00
SpaceEEC
d9262f2682 Added and fixed a bunch of docs stuff (#1767)
- Fixed a common copy paste fail `the the <thing>` in various places
- Apparently I can't type Resolvable correctly,
Fixed that wherever applicable
- Documented GroupDMChannel#nicks so that it will be displayed on the docs
- GroupDMChannel#icon is nullable
- Removed empty InviteOptions typdef, as its properties are now documented in GuildChannel#createInvite
- MessageMentions#channels is no longer nullable
- RoleData#permissions takes a PermissionResolvable or an array of them
- Webhook#avatar is nullable
- Added HTTPOptions typedef and added it to ClientOptions typedef
- ClientUserChannelOverride#muted is for a channel and not a guild directly
2017-08-10 20:31:10 +02:00
SpaceEEC
fa5c4efa2b Fixed a bunch of ClientUserGuildSettings stuff and its docs (#1758) 2017-08-10 01:25:24 +02:00
SpaceEEC
87cdad332c Improved Guild#createChannel, added RoleResolvable and fixed a bit of Emoji stuff (#1754)
* Made creating channels with overwrites nicer
and added ClientDataResolver#resolveRole

* Renamed ChannelPermissionOverwrites to ChannelCreationOverwrites

* Added RoleResolvables everywhere possible

* Fixed Emoji#setName resetting restricted roles and Emoji#equals

Which will lead to emojis not to update when roles are being added removed.
2017-08-10 01:22:57 +02:00
SpaceEEC
48b69c6e2f No longer double increment the reaction count when the client reacts (#1755) 2017-08-10 01:21:34 +02:00
SpaceEEC
a49709d329 Readded permissions to Role#edit's payload (#1760) 2017-08-10 01:18:13 +02:00
Raphael
25dd3bc29e updated docs for <ReactionEmoji>.toString() so it now uses send instead sendMessage in example (#1761) 2017-08-10 01:17:12 +02:00
Schuyler Cebulskie
54ff8ce596 Fix tern file 2017-08-06 18:15:34 -04:00
Schuyler Cebulskie
3682918df9 Update typings 2017-08-06 18:09:58 -04:00
Isabella
62fc9fce6d Add Attachment structure (#1731)
* Add Attachment structure

* Fix linter issues + @private

* Fixed array sends, also added embed sends

* fixed proving path to attachment

* fixed incorrect name assumption from path

* linting fix

* ;)

* im really good at this

* changes as requested by gus

and computer from #1459

* am a dum

* update webhook#send

* readonly addition to getters

* i... uh... oops

* farming deez commits

* fix webhook split

* removed some ugly

* removed .every checks
2017-08-06 18:09:47 -04:00
SpaceEEC
317a352337 Fix ClientUser#settings not showing up in the documentation (#1757) 2017-08-05 15:41:00 +02:00
Gus Caplan
e5be902568 where we're going we don't need referrers (#1749) 2017-08-04 10:46:10 +02:00
Gus Caplan
dab28a0906 Stop creating package-lock.json once and for all (#1753) 2017-08-04 10:45:41 +02:00
Gus Caplan
e5386e33a8 default channel doesn't exist anymore (#1738) 2017-08-04 10:21:16 +02:00
FireController1847
580e066a36 Init pause variable on VoiceBroadcast (#1751)
* Init pause variable on VoiceBroadcast

* Move it back. Could have swore I did this.
2017-08-04 09:21:18 +02:00
Yoson Chiu
ba1c257bb2 Fixes #1693 (#1745)
* Update AudioPlayer.js

* Set timestamp to 0 as well.
2017-08-04 09:18:37 +02:00
SpaceEEC
abfda7c3cc Fixed ClientUser#createGroupDM on user accounts and added some more GroupDMChannel stuff (#1747)
* ClientUser#createGroupDM now works like the docs states on user accounts

* Added GroupDMChannel#setIcon and fixed null handling for the channel name

* Added an s

* Don't resolve when icon is falsy and removed useless name trimming

* Removed now unnecessary name constant

* vscode being great

* Added GroupDMChannel#iconURL
2017-08-04 09:17:46 +02:00
Will Nelson
a30fc87816 fix reply splitting (#1750) 2017-08-04 09:17:10 +02:00
Gus Caplan
fd11381cc5 fix more race conditions (#1740)
* Update ClientUser.js

* Update ClientUserGuildSettings.js
2017-08-01 05:42:22 +02:00
Gus Caplan
4b77f26851 Update ClientUser.js (#1739) 2017-08-01 05:35:59 +02:00
Gus Caplan
963cf42e0d add MessageMentions#has, remove old method (#1724)
* Update MessageMentions.js

* remove old method

* smh

* Update Message.js

* Update MessageMentions.js

* Update MessageMentions.js

* Update MessageMentions.js
2017-08-01 04:49:00 +02:00
Pg Biel
5799ba28f9 Fix Guild.equals (#1713) 2017-08-01 04:48:46 +02:00
Crawl
73761245cc Update typings 2017-08-01 04:41:26 +02:00
Crawl
bda72c60fa CRLF to LF 2017-08-01 04:40:39 +02:00
iCrawl
d4793bae0f Fix tiny doc string 2017-08-01 04:32:29 +02:00
stupid cat
b8034525e3 Add user_guild_settings support (#1365)
* user guild settings

* Use direct collection

* I'm a goof

* double goof

* Structure properties

* Forgot to register listener

* wrong class names

* No more get in docs

* avoid waterfalls, bot checks

* trycatch

wow i thought i already did this :notlikecat:

* 👀

* Update ClientUser.js

* Update ClientUserGuildSettings.js

* Update UserGuildSettingsUpdate.js

* Update ClientUserChannelOverride.js

* Update ClientUserGuildSettings.js
2017-08-01 04:28:15 +02:00
tjpc3
4f5d1bffaf fix node.js crash due to error messages being called with invalid error keys (#1728)
* Comments

* More Comments

* Added new error message

* Fixed error message

* Removing temporary comments

* Fixed error messages

* Added more new error messages

* Removed trailing space

* Removed other trailing space

* Changed error key

* Changed error key used
2017-08-01 04:01:45 +02:00
SpaceEEC
79fed1295c Fixed DiscordAPIError#message sometimes being undefined (#1735) 2017-07-31 01:18:55 +02:00
SpaceEEC
fe8f371d82 Fixed Client#guildMembersChunk's members collection's key being undefined. (#1736) 2017-07-31 01:16:50 +02:00
Gus Caplan
0acb0ac5dc fix unpack weird issues (#1729) 2017-07-29 22:02:56 +02:00
Schuyler Cebulskie
a46f606170 Fix Crawl/Drah garbage 2017-07-27 23:17:39 -04:00
Crawl
7b74b088ac Update nsfw prop 2017-07-28 04:53:23 +02:00
Pg Biel
eef87e5d97 Reasons (#1715)
* Add reasons

* How could I forget

* Hopefully fix conflicts
2017-07-27 03:14:04 +02:00
Raphael
27196c2f9f docs update to topics/voice playFile example (#1716)
* Update voice.md

* Update voice.md

* fixed my grammar

* added requested spaces
2017-07-27 03:13:35 +02:00
Gus Caplan
b2ab947180 fix guild audit log fetching of stuff (#1721)
* Update GuildAuditLogs.js

* Update GuildAuditLogs.js

* e
2017-07-27 03:12:41 +02:00
iCrawl
a8e77df168 Merge branch 'rewrite-ratelimit-route-builder' 2017-07-27 03:04:45 +02:00
Gus Caplan
91c9df2da3 Revert "Revert "retry on 500 (#1709)""
This reverts commit 317bf4f7cb.
2017-07-27 03:04:21 +02:00
Crawl
4adecf4aef rewrite ratelimiting and api route builder (#1667)
* rewrite ratelimiting and api route builder

* more stuff

* let people pass their own handlers

* Update burst.js

* Update RequestHandler.js

* Update burst.js

* Update sequential.js

* Update RequestHandler.js
2017-07-27 03:04:03 +02:00
bdistin
080996b5a9 fix sequential and burst ratelimiters from going on timeout because the queue is empty (#1722)
* create branch for me to work on

* fix sequential and burst ratelimiters from going on timeout because the queue is empty
2017-07-27 02:51:58 +02:00
Crawl
07178a0a2a Revert "rewrite ratelimiting and api route builder (#1667)"
This reverts commit a2eeafc75d.
2017-07-26 23:00:46 +02:00
Gus Caplan
317bf4f7cb Revert "retry on 500 (#1709)"
This reverts commit 57b6980313.
2017-07-26 23:00:08 +02:00
Will Nelson
8bd7b82110 update collectors (#1616)
* start new collector stuff

* bugfixes

* remove pointless cleanup method

* rename methods, events, and options; remove extraneous methods,

* update doc ref
2017-07-26 10:10:35 +02:00
aemino
e29a3ec08b Handle unexpected disconnects via packets (#1521) 2017-07-26 10:10:21 +02:00
aemino
4342ed29a8 Audio bitrate support (#1439)
* Audio bitrate support

Note: not implemented for VoiceBroadcasts

* Fix default args, auto bitrate

* Late night typos are the best

* Changes bitrate to kbps for VoiceChannel stuff

* Add methods to manipulate bitrate while encoding
2017-07-26 10:06:40 +02:00
Will Nelson
7eb9e65c41 check guild availability when aggregating client emojis (#1711) 2017-07-26 10:04:43 +02:00
SpaceEEC
278fe74a58 Adding reason parameter to GuildMember's methods (#1710)
* Added reason parameter to GuildMember's methods

* Reason parameters are optional
2017-07-26 10:04:25 +02:00
Gus Caplan
57b6980313 retry on 500 (#1709) 2017-07-22 23:21:50 +02:00
SpaceEEC
aeb8f85106 Guild#fetchMember's options paremeter should be optional (#1705) 2017-07-21 15:00:20 +02:00
Gus Caplan
a2eeafc75d rewrite ratelimiting and api route builder (#1667)
* rewrite ratelimiting and api route builder

* more stuff

* let people pass their own handlers

* Update burst.js

* Update RequestHandler.js

* Update burst.js

* Update sequential.js

* Update RequestHandler.js
2017-07-21 02:32:40 +02:00
SpaceEEC
11556c0b3b Moved all error strings to src/errors/messages and a few other things (#1695)
* Added missing error messages
As well as `Guild#setRolePosition` and `Guild#setChannelPosition`'s first arg validation
And fixed a typo in `Guild#setChannelPosition`
`roles` -> `channels`

* Reverted collection and Util constructors

* Removed leftover messages
Should have been in the second commit.

* It's a single invalid permission and removed unused flag error

* Fix INVALID_TOKEN -> TOKEN_INVALID as of #1703
2017-07-21 02:27:19 +02:00
Raphael
7a27b12b2b .applicationID and .ownerID return a Snowflake rather than a string (#1700) 2017-07-21 02:11:37 +02:00
Gus Caplan
8cf95dc9b3 update fetch member to work in a more consistent way (#1696)
* Update Guild.js

* Update Guild.js
2017-07-21 02:11:12 +02:00
Raphael
edfd50d003 afkChannelID returns a Snowflake rather than an string (#1697)
little update to <guild>.afkChannelID property in docs
2017-07-18 17:11:09 +02:00
Robin B
7f69c62ddc Fix docs for Application secret type (#1690)
Now a string (as supposed to be) instead of boolean.
2017-07-17 12:03:40 +02:00
meew0
2b230e8c6c Elaborate on the issue template checkboxes, fix spacing 2017-07-17 10:16:46 +02:00
SpaceEEC
fdb8f046b5 Fixing MessageEmbed's timestamp transforming (#1688)
when sending to discord
Also storing the timestamp in milliseconds when using setTimestamp
2017-07-16 17:55:51 +02:00
SpaceEEC
b7bbd395e8 Fix for GroupDMChannel#addUser and added removeUser, setName and edit (#1576)
* fixed GroupDMChannel#addUser, added setName and removeUser

and changed every `the Group DM`to `this Group DM`, for consistency

* added edit method

* delete method comes already with the Channel class

* brackets

* removed empty line
2017-07-16 14:15:54 +02:00
SpaceEEC
8580380541 fixed MessageEmbed#timestamp and changed attachFile to attachFiles (#1670)
* fixed MessageEmbed#timestamp and changed attachFile to attachFiles
as well as a few doc changes

* Embed#files shouldn't be a nested array
2017-07-16 14:11:49 +02:00
Gus Caplan
a965b3709a move nsfw to the new prop (#1687) 2017-07-16 14:04:40 +02:00
Raphael
111fa2da93 Fix typo in client.voiceConnections docs (#1679)
Fix typo in client.voiceConnections docs
2017-07-11 05:42:14 +02:00
FireController1847
e50bf2cdad Fix Recommended Shards (#1672) 2017-07-10 10:37:31 +01:00
SpaceEEC
c0e9ce2a1d functions for setTimeout should get the context bound and not applied (#1673) 2017-07-10 03:34:54 +02:00
Gus Caplan
4e5556ba09 important build stuff (#1663) 2017-07-08 07:16:46 +02:00
Crawl
116fcbd54e Oops, might use the right version number 2017-07-08 06:34:50 +02:00
Crawl
516c2025ba Use the uglifyjs-webpack-plugin beta on npm 2017-07-08 06:32:29 +02:00
Crawl
0c34f3a313 Update dependencies & make webpack great again 2017-07-05 11:53:53 +02:00
Gus Caplan
e3cd000ec0 update http options to fit discord spec (#1656)
* Update Constants.js

* Update APIRequest.js

* Update Invite.js

* Update Constants.js
2017-07-05 09:10:06 +01:00
Gus Caplan
bcbf834c95 use webhooks cache in guild audit log (#1660)
* Update GuildAuditLogs.js

* Update GuildAuditLogs.js

* Update GuildAuditLogs.js
2017-07-05 09:08:13 +01:00
Gus Caplan
7f809395af add new unique property (#1659) 2017-07-05 09:02:40 +01:00
Gus Caplan
39a3e72894 allow content in edit options like in message send options (#1657) 2017-07-05 09:01:07 +01:00
Gus Caplan
f8a1f2c23b fix this again (#1655) 2017-07-04 03:58:54 +02:00
Gus Caplan
e57bfc9313 undefined check to merge default (#1654) 2017-07-04 03:48:20 +02:00
Drahcirius
b1d9084345 Remove RichEmbed in favour of MessageEmbed (#1584)
* remove RichEmbed in favour of MessageEmbed

* fix provider typo
2017-07-04 00:53:22 +02:00
SpaceEEC
c42e53d70d Fixed User#fetchProfile, UserProfile#premium and added #flags (#1629)
* Fixed User#fetchProfile, UserProfile#premium and added #flags

* made UserProfile#flags a getter and stored the raw bitfield under UserProfile#_flags

* lowercased Flags
2017-07-04 00:28:53 +02:00
SpaceEEC
3da95d7e68 Corrected some docstrings (#1611)
* corrected some docstrings

* merge master

* fixed MessageSearchResult typedef and moved the note for the hit property to there
2017-07-04 00:22:48 +02:00
Gus Caplan
2eb3720001 move raw call so that any cache events happen before (#1653)
* move raw call so that any cache events happen before

* Update WebSocketConnection.js

* Update WebSocketConnection.js
2017-07-04 00:10:28 +02:00
aemino
afcf43aef6 Add VoiceConnection errors (#1649) 2017-07-04 00:09:38 +02:00
SpaceEEC
1c901cee7b Fixed wrong parenthesis for Webhook#send and Webhook#sendSlackMessage (#1648) 2017-07-04 00:09:07 +02:00
SpaceEEC
3fa880df5b Made (hopefully) all url related methods accept an options objects (#1617)
and removed a leftover in User#avatarURL
2017-07-04 00:08:24 +02:00
SpaceEEC
ee3a2415e4 Removed deprecated file option from MessageOptions (#1614) 2017-07-04 00:06:29 +02:00
bdistin
d266804953 rest api route fixes (#1645)
* start of the rest api router fixes.

* fix more missed code
2017-07-02 09:43:10 +01:00
bdistin
8da557faab Fix client.fetchApplication (#1644)
previously it returned: `this.api.oauth2.applications was not a function`, missed fixing with the api router change
2017-07-02 01:33:21 +01:00
aemino
2b56de7728 Expose DiscordAPIError and API error constants (#1641)
* Expose DiscordAPIError

* Expose API error constants

* Add typedef for APIError

* Integligently forgot to save file
2017-07-02 01:20:35 +01:00
aemino
62537b7deb Ignore setSpeaking requests when VC isn't connected (#1638) 2017-07-01 10:14:41 +01:00
Gus Caplan
5ecd5f7d69 REST API speed improvement (#1577) 2017-07-01 10:14:17 +01:00
Gus Caplan
6bc7b3e068 add user account checkbox (#1640) 2017-07-01 10:11:15 +01:00
Gavin Wainwright
7b44262346 Destructure certain imports (#1634) 2017-06-29 00:43:26 +01:00
SpaceEEC
029efe5cb0 Fixed Guild#deleteEmoji, it's now using the emoji's id (#1633) 2017-06-28 18:17:57 +01:00
Gus Caplan
5891c0b4d7 update tern file to actually work (#1630) 2017-06-28 15:29:49 +01:00
Gus Caplan
ead6d80c36 Fix toLowerCase errors in GuildAuditLogs (#1627) 2017-06-28 15:27:29 +01:00
Drahcirius
45cc175851 setTimeout should use args (#1623) 2017-06-27 20:22:17 +01:00
Will Nelson
0a337a4646 make token not enumerable (#1620) 2017-06-25 20:48:30 +01:00
Gus Caplan
63e54982f4 Errors Standardization (#1246)
* errors and stuff

* more errors

* all the errors

* fix build
2017-06-25 18:48:05 +01:00
Gus Caplan
602fe06f88 update docs for discord api error (#1575)
* aaaaa

* Update DiscordAPIError.js
2017-06-24 23:36:48 +01:00
Gus Caplan
cada8763a9 clean up cdn resources (#1597)
* Create Constants.js

* Update Constants.js
2017-06-24 23:32:48 +01:00
aemino
4ae4c97589 Fix VoiceConnection#authenticateFailed race condition (#1601) 2017-06-24 23:28:49 +01:00
SpaceEEC
201ecd25a2 renamed OAuth2Application#reset to resetSecret and added resetToken (#1541) 2017-06-24 23:26:09 +01:00
Gus Caplan
7f8cc9c297 sanity changes to search (#1593)
* Create Search.js

* Create Guild.js

* Create TextBasedChannel.js

* Create Search.js

* Create Search.js

* Create Guild.js

* Create TextBasedChannel.js

* Create Search.js
2017-06-24 23:23:45 +01:00
Mythic
fd79539ec3 Improve Message's ID attribute documentation (#1450)
Remove the implication that a Message object's ID is unique only to the channel it was sent on
Message ID's are snowflakes, and as stated in Discord's API documentation, globally unique throughout Discord
2017-06-24 23:21:21 +01:00
Morgan (Fallen)
e506995e4f Update voice and shard examples (#1608)
* Update voice.js

message.channel.sendMessage(...) to message.channel.send(...)

* Update shard.js

message.channel.sendMessage(...) to message.channel.send(...)

* Update voice.js

* Update shard.js

* Update voice.js
2017-06-24 23:20:29 +01:00
Mstrodl
1fadd0f859 Update avatar example for v12.0 (#1610)
User.displayAvatarURL was changed from a property to a method so I changed the example accordingly
2017-06-24 23:12:22 +01:00
SpaceEEC
e671a010cb added Guild#setExplicitContentFilter (#1583) 2017-06-24 23:03:37 +01:00
SpaceEEC
4f23822264 Wait for the websocket event when creating a guild (#1524)
* Wait for the websocket event when creating a guild

* using TOOK_TOO_LONG error

* resolve after timeout with an unavailable guild object
2017-06-23 20:49:56 +01:00
Gus Caplan
66cc5b2b53 URI Encoding for reasons (#1606) 2017-06-17 10:47:37 +01:00
SpaceEEC
00eebd34cb Correctly mapping overwrites when creating a channel and renamed all relevant property names as of #1562 (#1570)
* using correct properties to apply permissionOverwrites

and fixed `GuildChannel#clone`

* also arrays should be mapped and correct properties taking priority

* changed .deny and .allow to .denied and .allowed respectively

* whoops
2017-06-16 12:49:13 +02:00
DeJay
35e8601b3a Replacing ticks (#1589)
http://i.imgur.com/7Xbaawm.png
2017-06-13 21:55:54 +02:00
SpaceEEC
ecb8424f52 fixed typo in Guild#createEmoji (#1588) 2017-06-12 11:26:36 -04:00
Amish Shah
b694ab1b80 Add internal sharding options 2017-06-11 11:36:58 +01:00
Drahcirius
355b1cca4a Remove global flag from ffmpeg tutorial doc (#1582) 2017-06-10 23:54:17 +01:00
SpaceEEC
d6041f9fb3 Added Client#status and Message#type typedefs (#1571)
* typedef for MessageTypes and linked Client#status to Status

* should be singular

* typedef for Voiceconnection#status
2017-06-09 16:27:49 +02:00
Crawl
7b3a005b65 Remove createCollector from all channels 2017-06-08 14:51:21 +02:00
Crawl
0898e1dd5b Fix createMessageCollector example 2017-06-08 14:50:26 +02:00
Schuyler Cebulskie
3bf8192812 Switch to User#tag in web builds example 2017-06-07 23:00:43 -04:00
Évelyne Lachance
06f4c679d3 Add count optional argument to Collection methods (#1552)
* Add `count` optional argument to Collection methods

[NON-BREAKING CHANGE]
An optional `count` argument is added to the following methods:
- random() and randomKey()
- first() and firstKey()
- last() and lastKey()

If `count` is used, the method returns an array instead of only the value. Performance impact non-existent for existing code. Performance for returning an array has been measured and this is the fastest I could find (array[i] = value is faster than array.push()).

* Update Collection.js

Fixed spacing/line length errors according to suggestions by codacy/pr

* Fixed docs

Added proper `@returns {*|Array}` as the methods might return either. Also added params where missing (whoops)

* Further doc fixes

Per Crawl's comments, fixed (i + 1) spacing as well as fixed {Integer} to {number}

* random() and randomKey() fix

Per Hydra's comment, random() and randomKey() now ensures unique values.
I've also resolved potential issues with requesting a count higher than the collection size. A collection with 10 items will only ever return at most 10 items using the `count` property.

* Can I facepalm harder

Had wrong header comments ^_^

* Fixed for "values/value" and Omited

Also, added "Positive" integer check.

* looks like I "omitted" a change, there.

* Update Collection.js

* Update Collection.js

* Update Collection.js
2017-06-07 18:52:41 -04:00
FireController1847
1e47cfdd5d Add denied/allowed permissions to PermissionOverwrites (#1562)
* Add denied/allowed permissions to PermissionOverwrites

* Remove one accidental trailing space.

* Change to _denied/_allowed & denied/allowed

This could possible break if people use deny/allow, I assume, but that's okay.

* Update PermissionOverwrites.js

* Update PermissionOverwrites.js
2017-06-07 23:47:45 +02:00
SpaceEEC
577ab37a2b make User#displayAvatarURL a method and make it and avatarURL accept an options object (#1569)
* make User#displayAvatarURL a method

* make avatarURL and displayAvatarURL accept an object as options
2017-06-07 23:47:17 +02:00
aemino
4e79a885b8 Remove unused VoiceBroadcast#guaranteeOpusEngine (fixes #1556) (#1563) 2017-06-05 06:52:31 +02:00
Schuyler Cebulskie
28dc3e6a2e Utilise Object.values for Permissions.ALL 2017-06-02 00:36:34 -04:00
Schuyler Cebulskie
2f2481c65e Clean up Travis stuff MOAR 2017-06-02 00:34:18 -04:00
Schuyler Cebulskie
92e9c61eb6 Betterer Travis? Maybe? 2017-06-02 00:25:13 -04:00
Schuyler Cebulskie
2a96296e95 Identify version as development 2017-06-02 00:19:02 -04:00
Schuyler Cebulskie
45cf05746d Revise Travis scripts, and use only Node 8 2017-06-02 00:12:27 -04:00
Gus Caplan
a2520efa1a Use node 8 error code (#1557) 2017-06-01 21:14:42 +02:00
Crawl
37d6624ef1 Fix CRLF to LF 2017-06-01 10:45:56 +02:00
Crawl
375b89a94a Force node 8 2017-06-01 10:42:35 +02:00
Gus Caplan
63f5652ac2 object.entries (#1549)
* Update DiscordAPIError.js

* Update ClientUserSettings.js
2017-06-01 10:38:34 +02:00
aemino
c4a7ce12e6 Opus engine fetching: don't ignore non-missing errors (#1555)
* Opus engine fetching: don't ignore non-missing errors

* typo fix
2017-06-01 10:29:55 +02:00
Marko Kajzer
c84529c102 Fixes #1548 (#1551)
* Added possibility to remove avatar

* Changed as requested

* Removed extra blank line
2017-06-01 06:06:46 +02:00
Amish Shah
980b58d4df Ignore package-lock.json 2017-05-30 23:32:54 +01:00
Crawl
47029feafa Bump to node 8 2017-05-30 21:25:53 +02:00
Tyler
7896081966 Fix <Role>.editable (#1547) 2017-05-30 15:36:04 +02:00
Gus Caplan
68c25fef28 Update Guild.js (#1545) 2017-05-30 15:34:06 +02:00
Amish Shah
535a640534 Update ws and tweetnacl dependencies to new major versions 2017-05-30 12:51:31 +01:00
Amish Shah
6cc74d22ff fml 2017-05-30 12:22:40 +01:00
Amish Shah
8f63368696 Correct documentation for VoiceConnection (see #1536) 2017-05-30 12:21:37 +01:00
Snazzah
29ead897d6 Add MEMBER_ROLE_UPDATE to returning 'UPDATE' array (#1538) (#1542) 2017-05-29 23:53:23 +02:00
Drahcirius
20a9e4a0f8 .send() not working on members (#1539) 2017-05-29 15:19:42 +02:00
Gus Caplan
1aa2293ebf add nsfw option to search (#1534)
* Update Search.js

* Update TextBasedChannel.js

* Update Search.js
2017-05-29 15:19:31 +02:00
PhoenixShay
22e8237bf1 Fix Util.js : fetchRecommendedShards() (#1532)
* Fix Util.js : fetchRecommendedShards()

I'm not sure who thought this was a good idea, but by removing gateway, it broke fetchRecommendedShards() in Util.js as it uses ${Constants.Endpoints.gateway.bot}.

* Update Constants.js

* Update Constants.js

* Update Util.js

* Update Constants.js
2017-05-28 22:54:56 +02:00
Drahcirius
555317043e Message embeds (#1529)
* wowe

* fix sending

* Update MessageEmbed.js

* lel

* patched some fields for message embed and transforms edits as well

* webhook embeds transform

* apply transform to webhook embeds, and changed references

* Update MessageEmbed.js

* Update ClientDataResolver.js

* updated embeds params and use new util resolvers

* did not mean to add this back

* use master version of ClientDataResolver

* transform no longer needed
2017-05-28 03:34:30 +02:00
SpaceEEC
afe0bd8bc4 User#defaultAvatarURL should use CDN (#1531) 2017-05-27 22:04:19 +02:00
Amish Shah
ee679c7320 Fix #1528 2017-05-27 19:19:35 +01:00
Drahcirius
4292134647 Refactored static resolvers to Util (#1517)
* ready event will now throw errors properly

* ws login rejection fix

* moved static resolves to util
2017-05-23 12:18:18 +02:00
Crawl
7309e367f1 Update typings 2017-05-23 11:14:25 +02:00
Crawl
05a9f7e72f Remove duplicate resolveString call 2017-05-22 01:04:27 +02:00
bdistin
75eb0bae58 Add resolve content back into send (#1516)
so arrays are joined again, instead of sent as one new message per element
2017-05-22 01:02:08 +02:00
Gus Caplan
694f8278f1 make fetching members way better (#1124)
* make fetching members way better

* fix up fetching edge cases yet again

* stop making useless collections

* Update Guild.js

* Update Guild.js

* consistency?

* Update GuildMembersChunk.js

* Update Guild.js

* Update Guild.js

* Open editor to fix issues instead of GH: check
2017-05-21 22:09:37 +02:00
SpaceEEC
fce15ba33c Fix for bulkDelete, acknowledge, createInvite and remove some redundant stuff (#1515) 2017-05-21 22:04:57 +02:00
Gus Caplan
a0df2c5fa4 they can be more than just string/num/bool (#1448) 2017-05-21 21:24:36 +02:00
bdistin
ec5da9e6ad Fix trying to use this.client, when this IS client, and this.client i… (#1514) 2017-05-21 21:12:49 +02:00
vzwGrey
874e94992b Fix reaction collector example (#1513) 2017-05-21 18:56:17 +02:00
Gus Caplan
0baa59b679 Internal API Request Rewrite (#1490)
* start rewrite

* converted guilds

* more changes

* convert GuildMember

* convert User and remove friend methods which kill people

* convert more stuff

* even more stuff

* make things nicer

* speed and fixes and stuff

* almost finished

* fix

* Update Client.js

* uwu

* Update RESTMethods.js

* message editing

* fix router

* fix issue with references

* message delete reason

* move message sending

* fix dm

* message splitting

* NO MORE REST METHODS

* Update Client.js

* Update WebhookClient.js

* remove all those endpoints from the constants

* Update ClientUser.js

* Update ClientUser.js

* fixes

* Update ClientUser.js

* complaiancy

* all sort of fixes

* merge master (#1)

* Fix Permissions now that member is deprecated (#1491)

* removing more deprecation leftovers (#1492)

* Fix MessageCollectors

* Fix awaitMessages (#1493)

* Fix MessageCollector#cleanup

* Fix MessageCollector#postCheck

* Add max option back for safety

* Update Invite.js (#1496)

* guild setPosition missing docs (#1498)

* missing docs

* update return docs

* indent

* switched .invites for the apirouter and invite.js

* make multiple options an object

* Update ClientUser.js

* fix nicks

* Update WebhookClient.js
2017-05-21 07:04:19 +02:00
Crawl
02f03c439f Update typings 2017-05-21 06:41:25 +02:00
Gus Caplan
7934788c10 you can't mutate a socket event in some browsers (webpack fix) (#1512) 2017-05-21 05:19:53 +02:00
Crawl
79253544ea Relink permission#FLAGS on docs 2017-05-20 21:04:31 +02:00
Crawl
284bec80d4 Fix MessageCollectorOptions docs 2017-05-20 00:03:51 +02:00
bdistin
4aa734b9ef guild setPosition missing docs (#1498)
* missing docs

* update return docs
2017-05-16 16:11:11 +02:00
Gus Caplan
3fa87de594 Update Invite.js (#1496) 2017-05-16 15:25:42 +02:00
Crawl
4955b1ce5f Add max option back for safety 2017-05-16 04:58:13 +02:00
Crawl
8beefe66d5 Fix MessageCollector#postCheck 2017-05-16 04:47:53 +02:00
Crawl
20a267c12f Fix MessageCollector#cleanup 2017-05-15 01:33:10 +02:00
Daniel Odendahl
88444cdd26 Fix awaitMessages (#1493) 2017-05-15 01:04:57 +02:00
Crawl
a579967eb9 Fix MessageCollectors 2017-05-15 00:48:35 +02:00
SpaceEEC
37a3a6baf9 removing more deprecation leftovers (#1492) 2017-05-14 23:44:39 +02:00
bdistin
25096047f1 Fix Permissions now that member is deprecated (#1491) 2017-05-14 22:40:06 +02:00
Crawl
ca926ee404 Remove all deprecated methods / props 2017-05-14 20:15:55 +02:00
Gus Caplan
4422f2aa8a fix infinte loop issue (#1488) 2017-05-14 19:33:04 +02:00
Crawl
342c644043 Improve avatar example 2017-05-14 19:30:23 +02:00
Crawl
5db3ab742b Update travis build stages 2017-05-13 19:09:26 +02:00
Crawl
833bfa1cba Move node versions 2017-05-13 19:04:30 +02:00
Crawl
b4645685aa Improve test and build scripts 2017-05-13 18:58:56 +02:00
Crawl
eab5c9e7f1 Add tarvis staging 2017-05-13 18:42:15 +02:00
Crawl
b0d4b53d6b Fix webpack uglify 2017-05-13 18:17:25 +02:00
Gus Caplan
6ac2252794 make default avatar resolving better (#1484)
* Update Constants.js

* Update User.js

* Update Constants.js

* Update Constants.js
2017-05-13 17:41:32 +02:00
SpaceEEC
ff3e602134 Failing to resolve a role should reject and not throw an error (#1483) 2017-05-12 15:30:46 +02:00
aemino
ff82297073 GuildMember#setVoiceChannel fix (#1482)
Looks like someone forgot to remove the full channel object from the PATCH payload.
2017-05-12 06:41:40 +02:00
Drahcirius
d11a658f40 invalid token errors not rejected properly (#1478)
* ready event will now throw errors properly

* ws login rejection fix
2017-05-10 11:14:39 -04:00
meew0
83f2c62c3f Fix the mention example in the USERS_PATTERN doc comment
Previously it was a channel mention. Thanks @Hackzzila.
2017-05-10 13:11:21 +02:00
SpaceEEC
f95f18b586 Handing promise rejections from GuildAuditLogs#build to the user (#1474)
* handing guildauditlog's promise rejections to the user

* Returning a new Promise to resolve a Promise.all is unnecessary.
Also for the docs, it returns a Promise<GuildauditLogs>, not GuildAuditLogs directly.

* totally did not removed that line
2017-05-09 00:19:24 +02:00
1Computer1
6566c0d3c5 Deprecate aliases (#1469) 2017-05-06 01:22:15 +02:00
SpaceEEC
5bfc688bb0 Using a traditional for loop rather than a for in loop for options.files (#1461) 2017-05-06 01:09:01 +02:00
SpaceEEC
e66fa145d2 fix fetchMentions' auth header, options and data mapping (#1457)
* fix fetchMentions' auth header, options and data mapping

* vscode strikes again

* switched to Util.mergeDefault

* vscode

* removed duplicated optionals and switched to instanceof
2017-05-06 01:04:12 +02:00
SpaceEEC
d9e5bdea19 added Invite#presenceCount and Invite#memberCount (#1460)
* added Invite#online and Invite#memberCount

* requested change
2017-05-05 23:24:02 +02:00
SpaceEEC
a685d24504 using correct properties for invites (#1467) 2017-05-05 23:19:07 +02:00
SpaceEEC
a4e5713790 readded docs for Client#error and Client#ready (#1466) 2017-05-05 20:15:06 +02:00
SpaceEEC
128b4ee3e8 update GuildAuditLogs for MESSAGE_DELETE and fixed extras (#1464)
* update GuildAuditLogs for MESSAGE_DELETE and fixed extras

* correct oder of targets
2017-05-05 19:44:54 +02:00
Crawl
2a23941020 Update version 2017-05-05 17:08:41 +02:00
SpaceEEC
e6437388cf Endpoints.Guild(...).Emoji(...) should not use CDN (#1462) 2017-05-05 02:22:55 +02:00
Crawl
8c6167d35a Update welcome docs page 2017-05-05 01:56:00 +02:00
Gus Caplan
caf96339e0 Update GuildAuditLogs.js (#1456) 2017-05-04 00:50:08 +02:00
Anxeal
ac5d4d1050 Fix typo in RESTMethods.js (#1455)
Mentions should be written with a capital M
2017-05-03 20:35:24 +01:00
Anxeal
3d92c6d316 Fix typo in RESTMethods.js (#1454)
fetchMeMentions -> fetchMentions 🤔
2017-05-03 19:45:51 +01:00
SpaceEEC
07623d49e2 Fix for sending files with Webhook class (#1449) 2017-05-02 06:58:42 +01:00
Amish Shah
a7c902c6cf New is also optional 2017-05-01 22:11:04 +01:00
Amish Shah
b7a81ed7e1 watch me, gus 2017-05-01 22:07:20 +01:00
Amish Shah
7da53af0c3 Improve GuildAuditLogs documentation by creating an AuditLogChange typedef 2017-05-01 21:08:15 +01:00
Cody A. Taylor
e124ada962 Document flattenErrors keys param (#1447)
* Document flattenErrors keys param.

* Remove parens.

* Capitalise a letter
2017-05-01 20:49:45 +01:00
Gus Caplan
35ef9cd33d Add Guild#nameAcronym and make avatar/iconURLs into functions (#1144)
* Guild#iconURL(format, size);
* OAuth2Application#iconURL(format, size);
* User#iconURL(format, size);
2017-05-01 20:37:00 +01:00
318 changed files with 32980 additions and 12580 deletions

View File

@@ -1,44 +1,66 @@
{
"extends": "eslint:recommended",
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"plugins": ["import"],
"parserOptions": {
"ecmaVersion": 6
"ecmaVersion": 2020
},
"env": {
"es6": true,
"es2020": true,
"node": true
},
"overrides": [{ "files": ["*.browser.js"], "env": { "browser": true } }],
"rules": {
"import/order": [
"error",
{
"groups": ["builtin", "external", "internal", "index", "sibling", "parent"],
"alphabetize": {
"order": "asc"
}
}
],
"prettier/prettier": [
2,
{
"printWidth": 120,
"singleQuote": true,
"quoteProps": "as-needed",
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid"
}
],
"strict": ["error", "global"],
"no-await-in-loop": "warn",
"no-compare-neg-zero": "error",
"no-extra-parens": ["warn", "all", {
"nestedBinaryExpressions": false
}],
"no-template-curly-in-string": "error",
"no-unsafe-negation": "error",
"valid-jsdoc": ["error", {
"requireReturn": false,
"requireReturnDescription": false,
"prefer": {
"return": "returns",
"arg": "param"
},
"preferType": {
"String": "string",
"Number": "number",
"Boolean": "boolean",
"Symbol": "symbol",
"object": "Object",
"function": "Function",
"array": "Array",
"date": "Date",
"error": "Error",
"null": "void"
"valid-jsdoc": [
"error",
{
"requireReturn": false,
"requireReturnDescription": false,
"prefer": {
"return": "returns",
"arg": "param"
},
"preferType": {
"String": "string",
"Number": "number",
"Boolean": "boolean",
"Symbol": "symbol",
"object": "Object",
"function": "Function",
"array": "Array",
"date": "Date",
"error": "Error",
"null": "void"
}
}
}],
],
"accessor-pairs": "warn",
"array-callback-return": "error",
"complexity": "warn",
"consistent-return": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-location": ["error", "property"],
@@ -77,6 +99,7 @@
"no-undef-init": "error",
"callback-return": "error",
"getter-return": "off",
"handle-callback-err": "error",
"no-mixed-requires": "error",
"no-new-require": "error",
@@ -95,7 +118,6 @@
"func-names": "error",
"func-name-matching": "error",
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
"indent": ["error", 2, { "SwitchCase": 1 }],
"key-spacing": "error",
"keyword-spacing": "error",
"max-depth": "error",
@@ -107,7 +129,6 @@
"no-array-constructor": "error",
"no-inline-comments": "error",
"no-lonely-if": "error",
"no-mixed-operators": "error",
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
"no-new-object": "error",
"no-spaced-func": "error",
@@ -117,14 +138,20 @@
"nonblock-statement-body-position": "error",
"object-curly-spacing": ["error", "always"],
"operator-assignment": "error",
"operator-linebreak": ["error", "after"],
"padded-blocks": ["error", "never"],
"quote-props": ["error", "as-needed"],
"quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
"semi-spacing": "error",
"semi": "error",
"space-before-blocks": "error",
"space-before-function-paren": ["error", "never"],
"space-before-function-paren": [
"error",
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",

View File

@@ -7,11 +7,12 @@ pull request. We use ESLint to enforce a consistent coding style, so having that
is a great boon to your development process.
## Setup
To get ready to work on the codebase, please do the following:
1. Fork & clone the repository, and make sure you're on the **master** branch
2. Run `npm install`
3. If you're working on voice, also run `npm install node-opus` or `npm install opusscript`
2. Run `npm ci`
3. If you're working on voice, also run `npm install @discordjs/opus` or `npm install opusscript`
4. Code your heart out!
5. Run `npm test` to run ESLint and ensure any JSDoc changes are valid
6. [Submit a pull request](https://github.com/discordjs/discord.js/compare)
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-next/blob/master/.github/COMMIT_CONVENTION.md))

11
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# These are supported funding model platforms
# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
# patreon: # Replace with a single Patreon username
# open_collective: # Replace with a single Open Collective username
# ko_fi: # Replace with a single Ko-fi username
# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
# custom: # Replace with a single custom sponsorship URL
github: amishshah
patreon: discordjs

View File

@@ -1,26 +0,0 @@
<!--
If you need help with discord.js installation or usage, please go to the discord.js Discord server instead:
https://discord.gg/bRCvFy9
This issue tracker is only for bug reports and enhancement suggestions. You won't receive any basic help here.
-->
**Please describe the problem you are having in as much detail as possible:**
**Include a reproducible code sample here, if possible:**
```js
```
**Further details:**
- discord.js version:
- node.js version:
- Operating system:
- Priority this issue should have please be realistic and elaborate if possible:
<!--
Ideally you would also test whether the issue occurs on the latest master branch commit.
If you have, please check the following box and insert the hash of the commit you tested:
-->
- [ ] I have also tested the issue on latest master, commit hash:

45
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,45 @@
---
name: Bug report
about: Report incorrect or unexpected behaviour of discord.js
title: ''
labels: 's: unverified, type: bug'
assignees: ''
---
<!--
If you need help with discord.js installation or usage, please go to the discord.js Discord server instead:
https://discord.gg/bRCvFy9
This issue tracker is only for bug reports and enhancement suggestions.
You won't receive any basic help here.
-->
**Please describe the problem you are having in as much detail as possible:**
**Include a reproducible code sample here, if possible:**
```js
// Place your code here
```
**Further details:**
- discord.js version:
- Node.js version:
- Operating system:
- Priority this issue should have please be realistic and elaborate if possible:
**Relevant client options:**
- partials: none
- gateway intents: none
- other: none
<!--
If this applies to you, please check the respective checkbox: [ ] becomes [x].
You don't have to modify the text to suit your particular situation if you want to
elaborate, please do so in the description.
While it's not a requirement to test your issue on the master branch, it would make fixing
the problem a lot easier for us, so please do so if possible.
-->
- [ ] I have also tested the issue on latest master, commit hash:

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Discord server
url: https://discord.gg/bRCvFy9
about: Have questions or need support? Please go to the Discord server, as issues that are just support-related will be closed and redirected there.

View File

@@ -0,0 +1,26 @@
---
name: Feature request
about: Request a feature for the core discord.js library
title: ''
labels: 'type: enhancement'
assignees: ''
---
<!--
If you need help with discord.js installation or usage, please go to the discord.js Discord server instead:
https://discord.gg/bRCvFy9
This issue tracker is only for bug reports and enhancement suggestions.
You likely won't receive any basic help here.
-->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Eg. I'm always frustrated when [...]
**Describe the ideal solution**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,7 +1,12 @@
**Please describe the changes this PR makes and why it should be merged:**
**Status**
- [ ] Code changes have been tested against the Discord API, or there are no code changes
- [ ] I know how to update typings and have done so, or typings don't need updating
**Semantic versioning classification:**
**Semantic versioning classification:**
- [ ] This PR changes the library's interface (methods or parameters added)
- [ ] This PR includes breaking changes (methods removed or renamed, parameters moved or removed)
- [ ] This PR **only** includes non-code changes, like changes to documentation, README, etc.

7
.github/SUPPORT.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# Seeking support?
We're sorry, we only use this issue tracker for bugs in the library itself and feature requests for it. We are not able to provide general support or answser questions on the issue tracker.
Should you want to ask such questions, please post in one of our support channels in our Discord server: https://discord.gg/bRCvFy9
Any issues that don't directly involve a bug in the library or a feature request will likely be closed and redirected to the Discord server.

18
.github/tsc.json vendored Normal file
View File

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

27
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: "CodeQL"
on:
push:
pull_request:
schedule:
- cron: '0 */12 * * 4'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 2
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: javascript
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

49
.github/workflows/deploy.yml vendored Normal file
View File

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

79
.github/workflows/test-cron.yml vendored Normal file
View File

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

77
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,77 @@
name: Testing
on: [push, pull_request]
jobs:
lint:
name: ESLint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Run ESLint
uses: icrawl/action-eslint@v1
typings:
name: TSLint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Run TSLint
run: npm run lint:typings
typescript:
name: TypeScript
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Register Problem Matcher
run: echo "##[add-matcher].github/tsc.json"
- name: Run TypeScript compiler
run: npm run test:typescript
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Install Node v12
uses: actions/setup-node@v1
with:
node-version: 12
- name: Install dependencies
run: npm ci
- name: Test documentation
run: npm run docs:test

2
.gitignore vendored
View File

@@ -17,5 +17,7 @@ deploy/deploy_key.pub
# Miscellaneous
.tmp/
.vscode/
.idea/
docs/docs.json
typings/index.js
webpack/

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "typings"]
path = typings
url = https://github.com/discordjs/discord.js-typings

View File

@@ -14,8 +14,6 @@ deploy/
.vscode/
docs/
webpack/
# NPM ignore
.eslintrc.json
.gitattributes
@@ -24,3 +22,5 @@ webpack/
webpack.config.js
.github/
test/
tsconfig.json
tslint.json

1
.npmrc
View File

@@ -1 +0,0 @@
package-json=false

View File

@@ -1,12 +1,8 @@
{
"ecmaVersion": 7,
"libs": [],
"loadEagerly": [
"./src/*.js"
],
"dontLoad": [
"node_modules/**"
],
"loadEagerly": ["./src/*.js"],
"dontLoad": ["node_modules/**"],
"plugins": {
"es_modules": {},
"node": {},
@@ -15,7 +11,7 @@
"strong": true
},
"webpack": {
"configPath": "./webpack.config.js",
"configPath": "./webpack.config.js"
}
}
}

View File

@@ -1,20 +0,0 @@
language: node_js
node_js:
- "6"
- "7"
cache:
directories:
- node_modules
install: npm install
script: bash ./deploy/test.sh
jobs:
include:
- stage: build
node_js: "6"
script: bash ./deploy/deploy.sh
env:
global:
- ENCRYPTION_LABEL: "af862fa96d3e"
- COMMIT_AUTHOR_EMAIL: "amishshah.2k@gmail.com"
dist: trusty
sudo: false

View File

@@ -175,7 +175,7 @@
END OF TERMS AND CONDITIONS
Copyright 2017 Amish Shah
Copyright 2015 - 2020 Amish Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -5,20 +5,34 @@
</p>
<br />
<p>
<a href="https://discord.gg/bRCvFy9"><img src="https://discordapp.com/api/guilds/222078108977594368/embed.png" alt="Discord server" /></a>
<a href="https://discord.gg/bRCvFy9"><img src="https://img.shields.io/discord/222078108977594368?color=7289da&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://travis-ci.org/discordjs/discord.js"><img src="https://travis-ci.org/discordjs/discord.js.svg" alt="Build status" /></a>
<a href="https://github.com/discordjs/discord.js/actions"><img src="https://github.com/discordjs/discord.js/workflows/Testing/badge.svg" alt="Build status" /></a>
<a href="https://david-dm.org/discordjs/discord.js"><img src="https://img.shields.io/david/discordjs/discord.js.svg?maxAge=3600" alt="Dependencies" /></a>
<a href="https://www.patreon.com/discordjs"><img src="https://img.shields.io/badge/donate-patreon-F96854.svg" alt="Patreon" /></a>
</p>
<p>
<a href="https://nodei.co/npm/discord.js/"><img src="https://nodei.co/npm/discord.js.png?downloads=true&stars=true" alt="NPM info" /></a>
<a href="https://nodei.co/npm/discord.js/"><img src="https://nodei.co/npm/discord.js.png?downloads=true&stars=true" alt="npm installnfo" /></a>
</p>
</div>
## Table of contents
- [About](#about)
- [Installation](#installation)
- [Audio engines](#audio-engines)
- [Optional packages](#optional-packages)
- [Example Usage](#example-usage)
- [Links](#links)
- [Extensions](#extensions)
- [Contributing](#contributing)
- [Help](#help)
## About
discord.js is a powerful [node.js](https://nodejs.org) module that allows you to interact with the
[Discord API](https://discordapp.com/developers/docs/intro) very easily.
discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to easily interact with the
[Discord API](https://discord.com/developers/docs/intro).
- Object-oriented
- Predictable abstractions
@@ -26,27 +40,32 @@ discord.js is a powerful [node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API
## Installation
**Node.js 6.0.0 or newer is required.**
**Node.js 12.0.0 or newer is required.**
Ignore any warnings about unmet peer dependencies, as they're all optional.
Without voice support: `npm install discord.js`
With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus`
With voice support ([@discordjs/opus](https://www.npmjs.com/package/@discordjs/opus)): `npm install discord.js @discordjs/opus`
With voice support ([opusscript](https://www.npmjs.com/package/opusscript)): `npm install discord.js opusscript`
### Audio engines
The preferred audio engine is node-opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose node-opus.
Using opusscript is only recommended for development environments where node-opus is tough to get working.
For production bots, using node-opus should be considered a necessity, especially if they're going to be running on multiple servers.
The preferred audio engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
### Optional packages
- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the WebSocket when *not* using uws (`npm install bufferutil`)
- [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack`)
- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
- [erlpack](https://github.com/discord/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discord/erlpack`)
- One of the following packages can be installed for faster voice packet encryption and decryption:
- [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws`)
- [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
## Example usage
```js
const Discord = require('discord.js');
const client = new Discord.Client();
@@ -65,23 +84,28 @@ 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))
* [Discord.js Discord server](https://discord.gg/bRCvFy9)
* [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://discordapi.com/unofficial/libs.html)
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
- [Documentation](https://discord.js.org/#/docs/main/master/general/welcome)
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide)) - this is still for stable
See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v12.html), including updated and removed items in the library.
- [Discord.js Discord server](https://discord.gg/bRCvFy9)
- [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://discordapi.com/unofficial/libs.html)
### Extensions
* [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
- [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
## 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/master/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [Discord.js Server](https://discord.gg/bRCvFy9).

View File

@@ -1,9 +0,0 @@
const browser = typeof window !== 'undefined';
const webpack = !!process.env.__DISCORD_WEBPACK__;
const Discord = require('./');
module.exports = Discord;
if (browser && webpack) window.Discord = Discord; // eslint-disable-line no-undef
// eslint-disable-next-line no-console
else if (!browser) console.warn('Warning: Attempting to use browser version of Discord.js in a non-browser environment!');

Binary file not shown.

View File

@@ -1,90 +0,0 @@
#!/bin/bash
# Adapted from https://gist.github.com/domenic/ec8b0fc8ab45f39403dd.
set -e
function build {
npm run docs
VERSIONED=false npm run webpack
}
# For revert branches, do nothing
if [[ "$TRAVIS_BRANCH" == revert-* ]]; then
echo -e "\e[36m\e[1mBuild triggered for reversion branch \"${TRAVIS_BRANCH}\" - doing nothing."
exit 0
fi
# For PRs, do nothing
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
echo -e "\e[36m\e[1mBuild triggered for PR #${TRAVIS_PULL_REQUEST} to branch \"${TRAVIS_BRANCH}\" - doing nothing."
exit 0
fi
# Figure out the source of the build
if [ -n "$TRAVIS_TAG" ]; then
echo -e "\e[36m\e[1mBuild triggered for tag \"${TRAVIS_TAG}\"."
SOURCE=$TRAVIS_TAG
SOURCE_TYPE="tag"
else
echo -e "\e[36m\e[1mBuild triggered for branch \"${TRAVIS_BRANCH}\"."
SOURCE=$TRAVIS_BRANCH
SOURCE_TYPE="branch"
fi
# For Node != 6, do nothing
if [ "$TRAVIS_NODE_VERSION" != "6" ]; then
echo -e "\e[36m\e[1mBuild triggered with Node v${TRAVIS_NODE_VERSION} - doing nothing."
exit 0
fi
build
# Initialise some useful variables
REPO=`git config remote.origin.url`
SSH_REPO=${REPO/https:\/\/github.com\//git@github.com:}
SHA=`git rev-parse --verify HEAD`
# Decrypt and add the ssh key
ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key"
ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv"
ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR}
ENCRYPTED_IV=${!ENCRYPTED_IV_VAR}
openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in deploy/deploy-key.enc -out deploy-key -d
chmod 600 deploy-key
eval `ssh-agent -s`
ssh-add deploy-key
# Checkout the repo in the target branch so we can build docs and push to it
TARGET_BRANCH="docs"
git clone $REPO out -b $TARGET_BRANCH
# Move the generated JSON file to the newly-checked-out repo, to be committed and pushed
mv docs/docs.json out/$SOURCE.json
# Commit and push
cd out
git add .
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git commit -m "Docs build for ${SOURCE_TYPE} ${SOURCE}: ${SHA}" || true
git push $SSH_REPO $TARGET_BRANCH
# Clean up...
cd ..
rm -rf out
# ...then do the same once more for the webpack
TARGET_BRANCH="webpack"
git clone $REPO out -b $TARGET_BRANCH
# Move the generated webpack over
mv webpack/discord.js out/discord.$SOURCE.js
mv webpack/discord.min.js out/discord.$SOURCE.min.js
# Commit and push
cd out
git add .
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
git commit -m "Webpack build for ${SOURCE_TYPE} ${SOURCE}: ${SHA}" || true
git push $SSH_REPO $TARGET_BRANCH

View File

@@ -1,34 +0,0 @@
#!/bin/bash
set -e
function tests {
npm run lint
npm run docs:test
exit 0
}
# For revert branches, do nothing
if [[ "$TRAVIS_BRANCH" == revert-* ]]; then
echo -e "\e[36m\e[1mTest triggered for reversion branch \"${TRAVIS_BRANCH}\" - doing nothing."
exit 0
fi
# For PRs
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
echo -e "\e[36m\e[1mTest triggered for PR #${TRAVIS_PULL_REQUEST} to branch \"${TRAVIS_BRANCH}\" - only running tests."
tests
fi
# Figure out the source of the test
if [ -n "$TRAVIS_TAG" ]; then
echo -e "\e[36m\e[1mTest triggered for tag \"${TRAVIS_TAG}\"."
else
echo -e "\e[36m\e[1mTest triggered for branch \"${TRAVIS_BRANCH}\"."
fi
# For Node != 6
if [ "$TRAVIS_NODE_VERSION" != "6" ]; then
echo -e "\e[36m\e[1mTest triggered with Node v${TRAVIS_NODE_VERSION} - only running tests."
tests
fi

View File

@@ -0,0 +1,163 @@
# Sending Attachments
In here you'll see a few examples showing how you can send an attachment using discord.js.
## Sending an attachment using a URL
There are a few ways you can do this, but we'll show you the easiest.
The following examples use [MessageAttachment](/#/docs/main/master/class/MessageAttachment).
```js
// Extract the required classes from the discord.js module
const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// If the message is '!rip'
if (message.content === '!rip') {
// Create the attachment using MessageAttachment
const attachment = new MessageAttachment('https://i.imgur.com/w3duR07.png');
// Send the attachment in the message channel
message.channel.send(attachment);
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
And here is the result:
![Image showing the result](/static/attachment-example1.png)
But what if you want to send an attachment with a message content? Fear not, for it is easy to do that too! We'll recommend reading [the TextChannel's "send" function documentation](/#/docs/main/master/class/TextChannel?scrollTo=send) to see what other options are available.
```js
// Extract the required classes from the discord.js module
const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// If the message is '!rip'
if (message.content === '!rip') {
// Create the attachment using MessageAttachment
const attachment = new MessageAttachment('https://i.imgur.com/w3duR07.png');
// Send the attachment in the message channel with a content
message.channel.send(`${message.author},`, attachment);
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
And here's the result of this one:
![Image showing the result](/static/attachment-example2.png)
## Sending a local file or buffer
Sending a local file isn't hard either! We'll be using [MessageAttachment](/#/docs/main/master/class/MessageAttachment) for these examples too.
```js
// Extract the required classes from the discord.js module
const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// If the message is '!rip'
if (message.content === '!rip') {
// Create the attachment using MessageAttachment
const attachment = new MessageAttachment('./rip.png');
// Send the attachment in the message channel with a content
message.channel.send(`${message.author},`, attachment);
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
The results are the same as the URL examples:
![Image showing result](/static/attachment-example2.png)
But what if you have a buffer from an image? Or a text document? Well, it's the same as sending a local file or a URL!
In the following example, we'll be getting the buffer from a `memes.txt` file, and send it in the message channel.
You can use any buffer you want, and send it. Just make sure to overwrite the filename if it isn't an image!
```js
// Extract the required classes from the discord.js module
const { Client, MessageAttachment } = require('discord.js');
// Import the native fs module
const fs = require('fs');
// Create an instance of a Discord client
const client = new Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// If the message is '!memes'
if (message.content === '!memes') {
// Get the buffer from the 'memes.txt', assuming that the file exists
const buffer = fs.readFileSync('./memes.txt');
/**
* Create the attachment using MessageAttachment,
* overwritting the default file name to 'memes.txt'
* Read more about it over at
* http://discord.js.org/#/docs/main/master/class/MessageAttachment
*/
const attachment = new MessageAttachment(buffer, 'memes.txt');
// Send the attachment in the message channel with a content
message.channel.send(`${message.author}, here are your memes!`, attachment);
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
And of course, the results are:
![Attachment File example 3](/static/attachment-example3.png)

View File

@@ -1,6 +1,8 @@
/*
Send a user a link to their avatar
*/
'use strict';
/**
* Send a user a link to their avatar
*/
// Import the discord.js module
const Discord = require('discord.js');
@@ -8,11 +10,10 @@ const Discord = require('discord.js');
// Create an instance of a Discord client
const client = new Discord.Client();
// The token of your bot - https://discordapp.com/developers/applications/me
const token = 'your bot token here';
// The ready event is vital, it means that your bot will only start reacting to information
// from Discord _after_ ready is emitted
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
@@ -22,9 +23,9 @@ client.on('message', message => {
// If the message is "what is my avatar"
if (message.content === 'what is my avatar') {
// Send the user's avatar URL
message.reply(message.author.avatarURL);
message.reply(message.author.displayAvatarURL());
}
});
// Log our bot in
client.login(token);
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');

40
docs/examples/embed.js Normal file
View File

@@ -0,0 +1,40 @@
'use strict';
/**
* An example of how you can send embeds
*/
// Extract the required classes from the discord.js module
const { Client, MessageEmbed } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// If the message is "how to embed"
if (message.content === 'how to embed') {
// We can create embeds using the MessageEmbed constructor
// Read more about all that you can do with the constructor
// over at https://discord.js.org/#/docs/main/master/class/MessageEmbed
const embed = new MessageEmbed()
// Set the title of the field
.setTitle('A slick little embed')
// Set the color of the embed
.setColor(0xff0000)
// Set the main content of the embed
.setDescription('Hello, this is a slick embed!');
// Send the embed to the same channel as the message
message.channel.send(embed);
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');

View File

@@ -1,6 +1,8 @@
/*
A bot that welcomes new guild members when they join
*/
'use strict';
/**
* A bot that welcomes new guild members when they join
*/
// Import the discord.js module
const Discord = require('discord.js');
@@ -8,11 +10,10 @@ const Discord = require('discord.js');
// Create an instance of a Discord client
const client = new Discord.Client();
// The token of your bot - https://discordapp.com/developers/applications/me
const token = 'your bot token here';
// The ready event is vital, it means that your bot will only start reacting to information
// from Discord _after_ ready is emitted
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
@@ -20,12 +21,12 @@ client.on('ready', () => {
// Create an event listener for new guild members
client.on('guildMemberAdd', member => {
// Send the message to a designated channel on a server:
const channel = member.guild.channels.find('name', 'member-log');
const channel = member.guild.channels.cache.find(ch => ch.name === 'member-log');
// Do nothing if the channel wasn't found on this server
if (!channel) return;
// Send the message, mentioning the member
channel.send(`Welcome to the server, ${member}`);
});
// Log our bot in
client.login(token);
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');

151
docs/examples/moderation.md Normal file
View File

@@ -0,0 +1,151 @@
# Moderation
In here, you'll see some basic examples for kicking and banning a member.
## Kicking a member
Let's say you have a member that you'd like to kick. Here is an example of how you _can_ do it.
```js
// Import the discord.js module
const Discord = require('discord.js');
// Create an instance of a Discord client
const client = new Discord.Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// Ignore messages that aren't from a guild
if (!message.guild) return;
// If the message content starts with "!kick"
if (message.content.startsWith('!kick')) {
// Assuming we mention someone in the message, this will return the user
// Read more about mentions over at https://discord.js.org/#/docs/main/master/class/MessageMentions
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
// Now we get the member from the user
const member = message.guild.member(user);
// If the member is in the guild
if (member) {
/**
* Kick the member
* Make sure you run this on a member, not a user!
* There are big differences between a user and a member
*/
member
.kick('Optional reason that will display in the audit logs')
.then(() => {
// We let the message author know we were able to kick the person
message.reply(`Successfully kicked ${user.tag}`);
})
.catch(err => {
// An error happened
// This is generally due to the bot not being able to kick the member,
// either due to missing permissions or role hierarchy
message.reply('I was unable to kick the member');
// Log the error
console.error(err);
});
} else {
// The mentioned user isn't in this guild
message.reply("That user isn't in this guild!");
}
// Otherwise, if no user was mentioned
} else {
message.reply("You didn't mention the user to kick!");
}
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
And the result is:
![Image showing the result](/static/kick-example.png)
## Banning a member
Banning works the same way as kicking, but it has slightly more options that can be changed.
```js
// Import the discord.js module
const Discord = require('discord.js');
// Create an instance of a Discord client
const client = new Discord.Client();
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
client.on('message', message => {
// Ignore messages that aren't from a guild
if (!message.guild) return;
// if the message content starts with "!ban"
if (message.content.startsWith('!ban')) {
// Assuming we mention someone in the message, this will return the user
// Read more about mentions over at https://discord.js.org/#/docs/main/master/class/MessageMentions
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
// Now we get the member from the user
const member = message.guild.member(user);
// If the member is in the guild
if (member) {
/**
* Ban the member
* Make sure you run this on a member, not a user!
* There are big differences between a user and a member
* Read more about what ban options there are over at
* https://discord.js.org/#/docs/main/master/class/GuildMember?scrollTo=ban
*/
member
.ban({
reason: 'They were bad!',
})
.then(() => {
// We let the message author know we were able to ban the person
message.reply(`Successfully banned ${user.tag}`);
})
.catch(err => {
// An error happened
// This is generally due to the bot not being able to ban the member,
// either due to missing permissions or role hierarchy
message.reply('I was unable to ban the member');
// Log the error
console.error(err);
});
} else {
// The mentioned user isn't in this guild
message.reply("That user isn't in this guild!");
}
} else {
// Otherwise, if no user was mentioned
message.reply("You didn't mention the user to ban!");
}
}
});
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');
```
And the result is:
![Image showing the result](/static/ban-example.png)

View File

@@ -1,6 +1,8 @@
/*
A ping pong bot, whenever you send "ping", it replies "pong".
*/
'use strict';
/**
* A ping pong bot, whenever you send "ping", it replies "pong".
*/
// Import the discord.js module
const Discord = require('discord.js');
@@ -8,11 +10,10 @@ const Discord = require('discord.js');
// Create an instance of a Discord client
const client = new Discord.Client();
// The token of your bot - https://discordapp.com/developers/applications/me
const token = 'your bot token here';
// The ready event is vital, it means that your bot will only start reacting to information
// from Discord _after_ ready is emitted
/**
* The ready event is vital, it means that only _after_ this will your bot start reacting to information
* received from Discord
*/
client.on('ready', () => {
console.log('I am ready!');
});
@@ -26,5 +27,5 @@ client.on('message', message => {
}
});
// Log our bot in
client.login(token);
// Log our bot in using the token from https://discord.com/developers/applications
client.login('your token here');

View File

@@ -1,11 +1,18 @@
/*
Send a message using a webhook
*/
'use strict';
/**
* Send a message using a webhook
*/
// Import the discord.js module
const Discord = require('discord.js');
// Create a new webhook
/*
* Create a new webhook
* The Webhooks ID and token can be found in the URL, when you request that URL, or in the response body.
* https://discord.com/api/webhooks/12345678910/T0kEn0fw3Bh00K
* ^^^^^^^^^^ ^^^^^^^^^^^^
* Webhook ID Webhook Token
*/
const hook = new Discord.WebhookClient('webhook id', 'webhook token');
// Send a message using the webhook

View File

@@ -1,23 +1,30 @@
# Frequently Asked Questions
These are just questions that get asked frequently, that usually have a common resolution.
If you have issues not listed here, please ask in the [official Discord server](https://discord.gg/bRCvFy9).
Always make sure to read the documentation.
These questions are some of the most frequently asked.
## No matter what, I get `SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode`‽
Update to Node.js 6.0.0 or newer.
Update to Node.js 12.0.0 or newer.
## How do I get voice working?
- Install FFMPEG.
- Install either the `node-opus` package or the `opusscript` package.
node-opus is greatly preferred, due to it having significantly better performance.
- Install either the `@discordjs/opus` package or the `opusscript` package.
@discordjs/opus is greatly preferred, due to it having significantly better performance.
## How do I install FFMPEG?
- **npm:** `npm install --save ffmpeg-binaries`
- **npm:** `npm install ffmpeg-static`
- **Ubuntu 16.04:** `sudo apt install ffmpeg`
- **Ubuntu 14.04:** `sudo apt-get install libav-tools`
- **Windows:** See the [FFMPEG section of AoDude's guide](https://github.com/bdistin/OhGodMusicBot/blob/master/README.md#download-ffmpeg).
- **Windows:** `npm install ffmpeg-static` or see the [FFMPEG section of AoDude's guide](https://github.com/bdistin/OhGodMusicBot/blob/master/README.md#download-ffmpeg).
## How do I set up node-opus?
- **Ubuntu:** Simply run `npm install node-opus`, and it's done. Congrats!
## How do I set up @discordjs/opus?
- **Ubuntu:** Simply run `npm install @discordjs/opus`, and it's done. Congrats!
- **Windows:** Run `npm install --global --production windows-build-tools` in an admin command prompt or PowerShell.
Then, running `npm install node-opus` in your bot's directory should successfully build it. Woo!
Then, running `npm install @discordjs/opus` in your bot's directory should successfully build it. Woo!
Other questions can be found at the [official Discord.js guide](https://discordjs.guide/popular-topics/common-questions.html)
If you have issues not listed here or on the guide, feel free to ask in the [official Discord.js server](https://discord.gg/bRCvFy9).
Always make sure to read the [documentation](https://discord.js.org/#/docs/main/stable/general/welcome).

View File

@@ -1,80 +1,93 @@
# Version 11.3.0
v11.3.0 backports many new features and bug fixes from the in-development v12.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.3.0) for a full list of changes, including information about deprecations.
# Version 12.0.0
# Version 11.2.0
v11.2.0 fixes a lot of bugs we encountered along the 11.1.0 release, as well as support for new features such as Message Attachments and UserGuildSettings.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.2.0) for a full list of changes, including information about deprecations.
v12.0.0 contains many new and improved features, optimisations, and bug fixes.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/12.0.0) for a full list of changes.
You can also visit [the guide](https://discordjs.guide/additional-info/changes-in-v12.html) for help with updating your v11 code to v12.
# Version 11.1.0
v11.1.0 features improved voice and gateway stability, as well as support for new features such as audit logs and searching for messages.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.1.0) for a full list of changes, including
information about deprecations.
# Version 11
Version 11 contains loads of new and improved features, optimisations, and bug fixes.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.0.0) for a full list of changes.
## Significant additions
* Message Reactions and Embeds (rich text)
* Support for uws and erlpack for better performance
* OAuthApplication support
* Web distributions
- Message Reactions and Embeds (rich text)
- Support for uws and erlpack for better performance
- OAuthApplication support
- Web distributions
## Breaking changes
### Client.login() no longer supports logging in with email + password
Logging in with an email and password has always been heavily discouraged since the advent of proper token support, but in v11 we have made the decision to completely remove the functionality, since Hammer & Chisel have [officially stated](https://github.com/hammerandchisel/discord-api-docs/issues/69#issuecomment-223886862) it simply shouldn't be done.
User accounts can still log in with tokens just like bot accounts. To obtain the token for a user account, you can log in to Discord with that account, and use Ctrl + Shift + I to open the developer tools. In the console tab, evaluating `localStorage.token` will give you the token for that account.
### ClientUser.setEmail()/setPassword() now require the current password, as well as setUsername() on user accounts
Since you can no longer log in with email and password, you must provide the current account password to the `setEmail()`, `setPassword()`, and `setUsername()` methods for user accounts (self-bots).
### Removed TextBasedChannel.sendTTSMessage()
This method was deemed to be an entirely pointless shortcut that virtually nobody even used.
The same results can be achieved by passing options to `send()` or `sendMessage()`.
Example:
```js
channel.send('Hi there', { tts: true });
```
### Using Collection.find()/exists() with IDs will throw an error
This is simply to help prevent a common mistake that is made frequently.
To find something or check its existence using an ID, you should use `.get()` and `.has()` which are part of the [ES6 Map class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map), which Collection is an extension of.
# Version 10
Version 10's non-BC changes focus on cleaning up some inconsistencies that exist in previous versions.
Upgrading from v9 should be quick and painless.
## Client options
All client options have been converted to camelCase rather than snake_case, and `max_message_cache` was renamed to `messageCacheMaxSize`.
v9 code example:
```js
const client = new Discord.Client({
disable_everyone: true,
max_message_cache: 500,
message_cache_lifetime: 120,
message_sweep_interval: 60
message_sweep_interval: 60,
});
```
v10 code example:
```js
const client = new Discord.Client({
disableEveryone: true,
messageCacheMaxSize: 500,
messageCacheLifetime: 120,
messageSweepInterval: 60
messageSweepInterval: 60,
});
```
## Presences
Presences have been completely restructured.
Previous versions of discord.js assumed that users had the same presence amongst all guilds - with the introduction of sharding, however, this is no longer the case.
v9 discord.js code may look something like this:
```js
User.status; // the status of the user
User.game; // the game that the user is playing
@@ -89,6 +102,7 @@ Additionally, the introduction of the Presence class keeps all of the presence d
A user may have an entirely different presence between two different guilds.**
v10 code:
```js
MemberOrUser.presence.status; // the status of the member or user
MemberOrUser.presence.game; // the game that the member or user is playing
@@ -98,41 +112,46 @@ ClientUser.setPresence(fullPresence); // status and game combined
```
## Voice
Voice has been rewritten internally, but in a backwards-compatible manner.
There is only one breaking change here; the `disconnected` event was renamed to `disconnect`.
Several more events have been made available to a VoiceConnection, so see the documentation.
## Events
Many events have been renamed or had their arguments change.
### Client events
| Version 9 | Version 10 |
|------------------------------------------------------|-----------------------------------------------|
| guildMemberAdd(guild, member) | guildMemberAdd(member) |
| guildMemberAvailable(guild, member) | guildMemberAvailable(member) |
| guildMemberRemove(guild, member) | guildMemberRemove(member) |
| guildMembersChunk(guild, members) | guildMembersChunk(members) |
| guildMemberUpdate(guild, oldMember, newMember) | guildMemberUpdate(oldMember, newMember) |
| guildRoleCreate(guild, role) | roleCreate(role) |
| guildRoleDelete(guild, role) | roleDelete(role) |
| guildRoleUpdate(guild, oldRole, newRole) | roleUpdate(oldRole, newRole) |
| Version 9 | Version 10 |
| ---------------------------------------------- | --------------------------------------- |
| guildMemberAdd(guild, member) | guildMemberAdd(member) |
| guildMemberAvailable(guild, member) | guildMemberAvailable(member) |
| guildMemberRemove(guild, member) | guildMemberRemove(member) |
| guildMembersChunk(guild, members) | guildMembersChunk(members) |
| guildMemberUpdate(guild, oldMember, newMember) | guildMemberUpdate(oldMember, newMember) |
| guildRoleCreate(guild, role) | roleCreate(role) |
| guildRoleDelete(guild, role) | roleDelete(role) |
| guildRoleUpdate(guild, oldRole, newRole) | roleUpdate(oldRole, newRole) |
The guild parameter that has been dropped from the guild-related events can still be derived using `member.guild` or `role.guild`.
### VoiceConnection events
| Version 9 | Version 10 |
|--------------|------------|
| ------------ | ---------- |
| disconnected | disconnect |
## Dates and timestamps
All dates/timestamps on the structures have been refactored to have a consistent naming scheme and availability.
All of them are named similarly to this:
**Date:** `Message.createdAt`
**Timestamp:** `Message.createdTimestamp`
All of them are named similarly to this:
**Date:** `Message.createdAt`
**Timestamp:** `Message.createdTimestamp`
See the docs for each structure to see which date/timestamps are available on them.
# Version 9
The version 9 (v9) rewrite takes a much more object-oriented approach than previous versions,
which allows your code to be much more readable and manageable.
It's been rebuilt from the ground up and should be much more stable, fixing caching issues that affected
@@ -145,19 +164,22 @@ into other more relevant classes where they belong.
Because of this, you will need to convert most of your calls over to the new methods.
Here are a few examples of methods that have changed:
* `Client.sendMessage(channel, message)` ==> `TextChannel.sendMessage(message)`
* `Client.sendMessage(user, message)` ==> `User.sendMessage(message)`
* `Client.updateMessage(message, "New content")` ==> `Message.edit("New Content")`
* `Client.getChannelLogs(channel, limit)` ==> `TextChannel.fetchMessages({options})`
* `Server.detailsOfUser(User)` ==> `Server.members.get(User).properties` (retrieving a member gives a GuildMember object)
* `Client.joinVoiceChannel(voicechannel)` => `VoiceChannel.join()`
- `Client.sendMessage(channel, message)` ==> `TextChannel.sendMessage(message)`
- `Client.sendMessage(user, message)` ==> `User.sendMessage(message)`
- `Client.updateMessage(message, "New content")` ==> `Message.edit("New Content")`
- `Client.getChannelLogs(channel, limit)` ==> `TextChannel.fetchMessages({options})`
- `Server.detailsOfUser(User)` ==> `Server.members.get(User).properties` (retrieving a member gives a GuildMember object)
- `Client.joinVoiceChannel(voicechannel)` => `VoiceChannel.join()`
A couple more important details:
* `Client.loginWithToken("token")` ==> `client.login("token")`
* `Client.servers.length` ==> `client.guilds.size` (all instances of `server` are now `guild`)
- `Client.loginWithToken("token")` ==> `client.login("token")`
- `Client.servers.length` ==> `client.guilds.size` (all instances of `server` are now `guild`)
## No more callbacks!
Version 9 eschews callbacks in favour of Promises. This means all code relying on callbacks must be changed.
Version 9 eschews callbacks in favour of Promises. This means all code relying on callbacks must be changed.
For example, the following code:
```js
@@ -167,7 +189,7 @@ client.getChannelLogs(channel, 100, function(messages) {
```
```js
channel.fetchMessages({limit: 100}).then(messages => {
channel.fetchMessages({ limit: 100 }).then(messages => {
console.log(`${messages.size} messages found`);
});
```

View File

@@ -1,15 +1,16 @@
<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>
<a href="https://discord.js.org"><img src="/static/logo.svg" width="546" alt="discord.js" id="djs-logo" /></a>
</p>
<br />
<p>
<a href="https://discord.gg/bRCvFy9"><img src="https://discordapp.com/api/guilds/222078108977594368/embed.png" alt="Discord server" /></a>
<a href="https://discord.gg/bRCvFy9"><img src="https://img.shields.io/discord/222078108977594368?color=7289da&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://travis-ci.org/discordjs/discord.js"><img src="https://travis-ci.org/discordjs/discord.js.svg" alt="Build status" /></a>
<a href="https://david-dm.org/discordjs/discord.js"><img src="https://img.shields.io/david/discordjs/discord.js.svg?maxAge=3600" alt="Dependencies" /></a>
<a href="https://www.patreon.com/discordjs"><img src="https://img.shields.io/badge/donate-patreon-F96854.svg" alt="Patreon" /></a>
</p>
<p>
<a href="https://nodei.co/npm/discord.js/"><img src="https://nodei.co/npm/discord.js.png?downloads=true&stars=true" alt="NPM info" /></a>
@@ -17,15 +18,13 @@
</div>
# Welcome!
Welcome to the discord.js v11.3 documentation.
The v11.3 release contains backports of many features and bug fixes from the in-development v12, such as categories and animated emoji support.
v12 is still very much a work-in-progress, as we're aiming to make it the best it can possibly be before releasing.
If you are fond of living life on the bleeding-edge, check out the master branch.
Welcome to the discord.js v12 documentation.
## About
discord.js is a powerful [node.js](https://nodejs.org) module that allows you to interact with the
[Discord API](https://discordapp.com/developers/docs/intro) very easily.
discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to easily interact with the
[Discord API](https://discord.com/developers/docs/intro).
- Object-oriented
- Predictable abstractions
@@ -33,27 +32,32 @@ discord.js is a powerful [node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API
## Installation
**Node.js 6.0.0 or newer is required.**
**Node.js 12.0.0 or newer is required.**
Ignore any warnings about unmet peer dependencies, as they're all optional.
Without voice support: `npm install discord.js`
With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus`
With voice support ([@discordjs/opus](https://www.npmjs.com/package/@discordjs/opus)): `npm install discord.js @discordjs/opus`
With voice support ([opusscript](https://www.npmjs.com/package/opusscript)): `npm install discord.js opusscript`
### Audio engines
The preferred audio engine is node-opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose node-opus.
Using opusscript is only recommended for development environments where node-opus is tough to get working.
For production bots, using node-opus should be considered a necessity, especially if they're going to be running on multiple servers.
The preferred audio engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
### Optional packages
- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the WebSocket when *not* using uws (`npm install bufferutil`)
- [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack`)
- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
- [erlpack](https://github.com/discord/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discord/erlpack`)
- One of the following packages can be installed for faster voice packet encryption and decryption:
- [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
- [uws](https://www.npmjs.com/package/uws) for a much faster WebSocket connection (`npm install uws`)
- [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
## Example usage
```js
const Discord = require('discord.js');
const client = new Discord.Client();
@@ -72,23 +76,28 @@ 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))
* [Discord.js Discord server](https://discord.gg/bRCvFy9)
* [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://discordapi.com/unofficial/libs.html)
- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
- [Documentation](https://discord.js.org/#/docs/main/master/general/welcome)
- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide)) - this is still for stable
See also the WIP [Update Guide](https://discordjs.guide/additional-info/changes-in-v12.html) also including updated and removed items in the library.
- [Discord.js Discord server](https://discord.gg/bRCvFy9)
- [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://discordapi.com/unofficial/libs.html)
### Extensions
* [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
- [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
## 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/master/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [Discord.js Server](https://discord.gg/bRCvFy9).

View File

@@ -12,13 +12,21 @@
path: voice.md
- name: Web builds
path: web.md
- name: Partials
path: partials.md
- name: Examples
files:
- name: Ping
path: ping.js
- name: Avatars
path: avatars.js
- name: Attachments
path: attachments.md
- name: Server greeting
path: greeting.js
- name: Message Embed
path: embed.js
- name: Moderation
path: moderation.md
- name: Webhook
path: webhook.js

65
docs/topics/partials.md Normal file
View File

@@ -0,0 +1,65 @@
# Partials
Partials allow you to receive events that contain uncached instances, providing structures that contain very minimal
data. For example, if you were to receive a `messageDelete` event with an uncached message, normally Discord.js would
discard the event. With partials, you're able to receive the event, with a Message object that contains just an ID.
## Opting in
Partials are opt-in, and you can enable them in the Client options by specifying [PartialTypes](/#/docs/main/master/typedef/PartialType):
```js
// Accept partial messages, DM channels, and reactions when emitting events
new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
```
## Usage & warnings
<warn>The only guaranteed data a partial structure can store is its ID. All other properties/methods should be
considered invalid/defunct while accessing a partial structure.</warn>
After opting-in with the above, you begin to allow partial messages and channels in your caches, so it's important
to check whether they're safe to access whenever you encounter them, whether it be in events or through normal cache
usage.
All instance of structures that you opted-in for will have a `partial` property. As you'd expect, this value is `true`
when the instance is partial. Partial structures are only guaranteed to contain an ID, any other properties and methods
no longer carry their normal type guarantees.
This means you have to take time to consider possible parts of your program that might need checks put in place to
prevent accessing partial data:
```js
client.on('messageDelete', message => {
console.log(`${message.id} was deleted!`);
// Partial messages do not contain any content so skip them
if (!message.partial) {
console.log(`It had content: "${message.content}"`);
}
});
// You can also try to upgrade partials to full instances:
client.on('messageReactionAdd', async (reaction, user) => {
// If a message gains a reaction and it is uncached, fetch and cache the message
// You should account for any errors while fetching, it could return API errors if the resource is missing
if (reaction.message.partial) await reaction.message.fetch();
// Now the message has been cached and is fully available:
console.log(`${reaction.message.author}'s message "${reaction.message.content}" gained a reaction!`);
// Fetches and caches the reaction itself, updating resources that were possibly defunct.
if (reaction.partial) await reaction.fetch();
// Now the reaction is fully available and the properties will be reflected accurately:
console.log(`${reaction.count} user(s) have given the same reaction to this message!`);
});
```
<info>If a message is deleted and both the message and channel are uncached, you must enable both 'MESSAGE' and
'CHANNEL' in the client options to receive the messageDelete event.</info>
## Why?
This allows developers to listen to events that contain uncached data, which is useful if you're running a moderation
bot or any bot that relies on still receiving updates to resources you don't have cached -- message reactions are a
good example.
Currently, the only type of channel that can be uncached is a DM channel, there is no reason why guild channels should
not be cached.

View File

@@ -1,16 +1,23 @@
# Introduction to Voice
Voice in discord.js can be used for many things, such as music bots, recording or relaying audio.
In discord.js, you can use voice by connecting to a `VoiceChannel` to obtain a `VoiceConnection`, where you can start streaming and receiving audio.
To get started, make sure you have:
* ffmpeg - `npm install ffmpeg-binaries`
* an opus encoder, choose one from below:
* `npm install opusscript`
* `npm install node-opus`
* a good network connection
- FFmpeg - `npm install ffmpeg-static`
- an opus encoder, choose one from below:
- `npm install @discordjs/opus` (better performance)
- `npm install opusscript`
- a good network connection
The preferred opus engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
## Joining a voice channel
The example below reacts to a message and joins the sender's voice channel, catching any errors. This is important
as it allows us to obtain a `VoiceConnection` that we can start to stream audio with.
@@ -20,19 +27,15 @@ const client = new Discord.Client();
client.login('token here');
client.on('message', message => {
client.on('message', async message => {
// Voice only works in guilds, if the message does not come from a guild,
// we ignore it
if (!message.guild) return;
if (message.content === '/join') {
// Only try to join the sender's voice channel if they are in one themselves
if (message.member.voiceChannel) {
message.member.voiceChannel.join()
.then(connection => { // Connection is an instance of VoiceConnection
message.reply('I have successfully connected to the channel!');
})
.catch(console.log);
if (message.member.voice.channel) {
const connection = await message.member.voice.channel.join();
} else {
message.reply('You need to join a voice channel first!');
}
@@ -41,69 +44,97 @@ client.on('message', message => {
```
## Streaming to a Voice Channel
In the previous example, we looked at how to join a voice channel in order to obtain a `VoiceConnection`. Now that we
have obtained a voice connection, we can start streaming audio to it. The following example shows how to stream an mp3
file:
have obtained a voice connection, we can start streaming audio to it.
### Introduction to playing on voice connections
The most basic example of playing audio over a connection would be playing a local file:
**Playing a file:**
```js
// To play a file, we need to give an absolute path to it
const dispatcher = connection.playFile('C:/Users/Discord/Desktop/myfile.mp3');
const dispatcher = connection.play('/home/discord/audio.mp3');
```
Your file doesn't have to be just an mp3; ffmpeg can convert videos and audios of many formats.
The `dispatcher` variable is an instance of a `StreamDispatcher`, which manages streaming a specific resource to a voice
channel. We can do many things with the dispatcher, such as finding out when the stream ends or changing the volume:
The `dispatcher` in this case is a `StreamDispatcher` - here you can control the volume and playback of the stream:
```js
dispatcher.on('end', () => {
// The song has finished
dispatcher.pause();
dispatcher.resume();
dispatcher.setVolume(0.5); // half the volume
dispatcher.on('finish', () => {
console.log('Finished playing!');
});
dispatcher.on('error', e => {
// Catch any errors that may arise
console.log(e);
dispatcher.destroy(); // end the stream
```
We can also pass in options when we first play the stream:
```js
const dispatcher = connection.play('/home/discord/audio.mp3', {
volume: 0.5,
});
```
### What can I play?
Discord.js allows you to play a lot of things:
```js
// ReadableStreams, in this example YouTube audio
const ytdl = require('ytdl-core');
connection.play(ytdl('https://www.youtube.com/watch?v=ZlAU_w7-Xp8', { filter: 'audioonly' }));
// Files on the internet
connection.play('http://www.sample-videos.com/audio/mp3/wave.mp3');
// Local files
connection.play('/home/discord/audio.mp3');
```
New to v12 is the ability to play OggOpus and WebmOpus streams with much better performance by skipping out Ffmpeg. Note this comes at the cost of no longer having volume control over the stream:
```js
connection.play(fs.createReadStream('./media.webm'), {
type: 'webm/opus',
});
dispatcher.setVolume(0.5); // Set the volume to 50%
dispatcher.setVolume(1); // Set the volume back to 100%
console.log(dispatcher.time); // The time in milliseconds that the stream dispatcher has been playing for
dispatcher.pause(); // Pause the stream
dispatcher.resume(); // Carry on playing
dispatcher.end(); // End the dispatcher, emits 'end' event
connection.play(fs.createReadStream('./media.ogg'), {
type: 'ogg/opus',
});
```
If you have an existing [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams),
this can also be used:
Make sure to consult the documentation for a full list of what you can play - there's too much to cover here!
**Playing a ReadableStream:**
```js
connection.playStream(myReadableStream);
## Voice Broadcasts
// If you don't want to use absolute paths, you can use
// fs.createReadStream to circumvent it
const fs = require('fs');
const stream = fs.createReadStream('./test.mp3');
connection.playStream(stream);
```
It's important to note that creating a readable stream to a file is less efficient than simply using `connection.playFile()`.
**Playing anything else:**
For anything else, such as a URL to a file, you can use `connection.playArbitraryInput()`. You should consult the [ffmpeg protocol documentation](https://ffmpeg.org/ffmpeg-protocols.html) to see what you can use this for.
A voice broadcast is very useful for "radio" bots, that play the same audio across multiple channels. It means audio is only transcoded once, and is much better on performance.
```js
// Play an mp3 from a URL
connection.playArbitraryInput('http://mysite.com/sound.mp3');
const broadcast = client.voice.createBroadcast();
broadcast.on('subscribe', dispatcher => {
console.log('New broadcast subscriber!');
});
broadcast.on('unsubscribe', dispatcher => {
console.log('Channel unsubscribed from broadcast :(');
});
```
Again, playing a file from a URL like this is more performant than creating a ReadableStream to the file.
`broadcast` is an instance of `VoiceBroadcast`, which has the same `play` method you are used to with regular VoiceConnections:
## Advanced Topics
soon:tm:
```js
const dispatcher = broadcast.play('./audio.mp3');
connection.play(broadcast);
```
It's important to note that the `dispatcher` stored above is a `BroadcastDispatcher` - it controls all the dispatcher subscribed to the broadcast, e.g. setting the volume of this dispatcher affects the volume of all subscribers.
## Voice Receive
coming soon&trade;

View File

@@ -1,13 +1,32 @@
# Web builds
In addition to your usual Node applications, discord.js has special distributions available that are capable of running in web browsers.
This is useful for client-side web apps that need to interact with the Discord API.
[Webpack 3](https://webpack.js.org/) is used to build these.
## Usage
## Restrictions
- Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries,
which web browsers do not support.
- The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards.
- None of the native optional packages are usable.
### Require Library
If you are making your own webpack project, you can require `discord.js/browser` wherever you need to use discord.js, like so:
```js
const Discord = require('discord.js/browser');
// do something with Discord like you normally would
```
### Webpack File
You can obtain your desired version of discord.js' web build from the [webpack branch](https://github.com/discordjs/discord.js/tree/webpack) of the GitHub repository.
There is a file for each branch and version of the library, and the ones ending in `.min.js` are minified to substantially reduce the size of the source code.
Include the file on the page just as you would any other JS library, like so:
```html
<script type="text/javascript" src="discord.VERSION.min.js"></script>
```
@@ -15,15 +34,10 @@ Include the file on the page just as you would any other JS library, like so:
Rather than importing discord.js with `require('discord.js')`, the entire `Discord` object is available as a global (on the `window`) object.
The usage of the API isn't any different from using it in Node.js.
## Restrictions
- Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries,
which web browsers do not support.
- The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards.
- None of the optional packages are usable, since they're native libraries.
#### Example
## Example
```html
<script type="text/javascript" src="discord.11.3.1.min.js"></script>
<script type="text/javascript" src="discord.11.1.0.min.js"></script>
<script type="text/javascript">
const client = new Discord.Client();

95
esm/discord.mjs Normal file
View File

@@ -0,0 +1,95 @@
import Discord from '../src/index.js';
export default Discord;
export const {
BaseClient,
Client,
Shard,
ShardClientUtil,
ShardingManager,
WebhookClient,
ActivityFlags,
BitField,
Collection,
Constants,
DataResolver,
BaseManager,
DiscordAPIError,
HTTPError,
MessageFlags,
Intents,
Permissions,
Speaking,
Snowflake,
SnowflakeUtil,
Structures,
SystemChannelFlags,
UserFlags,
Util,
version,
ChannelManager,
GuildChannelManager,
GuildEmojiManager,
GuildEmojiRoleManager,
GuildMemberManager,
GuildMemberRoleManager,
GuildManager,
ReactionManager,
ReactionUserManager,
MessageManager,
PresenceManager,
RoleManager,
UserManager,
discordSort,
escapeMarkdown,
fetchRecommendedShards,
resolveColor,
resolveString,
splitMessage,
Application,
Base,
Activity,
APIMessage,
BaseGuildEmoji,
CategoryChannel,
Channel,
ClientApplication,
ClientUser,
Collector,
DMChannel,
Emoji,
Guild,
GuildAuditLogs,
GuildChannel,
GuildEmoji,
GuildMember,
GuildPreview,
GuildTemplate,
Integration,
Invite,
Message,
MessageAttachment,
MessageCollector,
MessageEmbed,
MessageMentions,
MessageReaction,
NewsChannel,
PermissionOverwrites,
Presence,
ClientPresence,
ReactionCollector,
ReactionEmoji,
RichPresenceAssets,
Role,
StoreChannel,
Team,
TeamMember,
TextChannel,
User,
VoiceChannel,
VoiceRegion,
VoiceState,
Webhook,
WebSocket
} = Discord;

3
jsdoc.json Normal file
View File

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

11518
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,30 @@
{
"name": "discord.js",
"version": "11.3.2",
"version": "12.5.1",
"description": "A powerful library for interacting with the Discord API",
"main": "./src/index",
"types": "./typings/index.d.ts",
"exports": {
".": [
{
"require": "./src/index.js",
"import": "./esm/discord.mjs"
},
"./src/index.js"
],
"./esm": "./esm/discord.mjs"
},
"scripts": {
"test": "npm run lint && npm run docs:test",
"test": "npm run lint && npm run docs:test && npm run lint:typings",
"test:typescript": "tsc",
"docs": "docgen --source src --custom docs/index.yml --output docs/docs.json",
"docs:test": "docgen --source src --custom docs/index.yml",
"lint": "eslint src",
"lint:fix": "eslint --fix src",
"webpack": "parallel-webpack"
"lint:fix": "eslint src --fix",
"lint:typings": "tslint typings/index.d.ts",
"prettier": "prettier --write src/**/*.js typings/**/*.ts",
"build:browser": "webpack",
"prepublishOnly": "npm run test && cross-env NODE_ENV=production npm run build:browser"
},
"repository": {
"type": "git",
@@ -31,63 +45,119 @@
},
"homepage": "https://github.com/discordjs/discord.js#readme",
"runkitExampleFilename": "./docs/examples/ping.js",
"unpkg": "./webpack/discord.min.js",
"dependencies": {
"long": "^4.0.0",
"prism-media": "^0.0.2",
"snekfetch": "^3.6.4",
"tweetnacl": "^1.0.0",
"ws": "^4.0.0"
},
"peerDependencies": {
"bufferutil": "^3.0.3",
"erlpack": "discordapp/erlpack",
"node-opus": "^0.2.7",
"opusscript": "^0.0.6",
"sodium": "^2.0.3",
"libsodium-wrappers": "^0.7.3",
"uws": "^9.14.0"
"@discordjs/collection": "^0.1.6",
"@discordjs/form-data": "^3.0.1",
"abort-controller": "^3.0.0",
"node-fetch": "^2.6.1",
"prism-media": "^1.2.2",
"setimmediate": "^1.0.5",
"tweetnacl": "^1.0.3",
"ws": "^7.3.1"
},
"devDependencies": {
"@types/node": "^9.4.6",
"discord.js-docgen": "discordjs/docgen",
"eslint": "^4.18.0",
"parallel-webpack": "^2.2.0",
"uglifyjs-webpack-plugin": "^1.2.0",
"webpack": "^3.11.0"
"@commitlint/cli": "^11.0.0",
"@commitlint/config-angular": "^11.0.0",
"@types/node": "^12.12.6",
"@types/ws": "^7.2.7",
"cross-env": "^7.0.2",
"discord.js-docgen": "git+https://github.com/discordjs/docgen.git",
"dtslint": "^4.0.4",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.13.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.1.4",
"husky": "^4.3.0",
"jest": "^26.6.0",
"json-filter-loader": "^1.0.0",
"lint-staged": "^10.4.2",
"prettier": "^2.1.2",
"terser-webpack-plugin": "^4.2.3",
"tslint": "^6.1.3",
"typescript": "^4.0.3",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12"
},
"engines": {
"node": ">=6.0.0"
"node": ">=12.0.0"
},
"browser": {
"@discordjs/opus": false,
"https": false,
"ws": false,
"uws": false,
"erlpack": false,
"prism-media": false,
"opusscript": false,
"node-opus": false,
"tweetnacl": false,
"sodium": false,
"worker_threads": false,
"zlib-sync": false,
"src/sharding/Shard.js": false,
"src/sharding/ShardClientUtil.js": false,
"src/sharding/ShardingManager.js": false,
"src/client/voice/dispatcher/StreamDispatcher.js": false,
"src/client/voice/opus/BaseOpusEngine.js": false,
"src/client/voice/opus/NodeOpusEngine.js": false,
"src/client/voice/opus/OpusEngineList.js": false,
"src/client/voice/opus/OpusScriptEngine.js": false,
"src/client/voice/pcm/ConverterEngine.js": false,
"src/client/voice/pcm/ConverterEngineList.js": false,
"src/client/voice/pcm/FfmpegConverterEngine.js": false,
"src/client/voice/player/AudioPlayer.js": false,
"src/client/voice/receiver/VoiceReadable.js": false,
"src/client/voice/receiver/VoiceReceiver.js": false,
"src/client/voice/util/Secretbox.js": false,
"src/client/voice/util/SecretKey.js": false,
"src/client/voice/util/VolumeInterface.js": false,
"src/client/voice/ClientVoiceManager.js": false,
"src/client/voice/VoiceBroadcast.js": false,
"src/client/voice/VoiceConnection.js": false,
"src/client/voice/VoiceUDPClient.js": false,
"src/client/voice/VoiceWebSocket.js": false
"src/client/voice/dispatcher/BroadcastDispatcher.js": false,
"src/client/voice/dispatcher/StreamDispatcher.js": false,
"src/client/voice/networking/VoiceUDPClient.js": false,
"src/client/voice/networking/VoiceWebSocket.js": false,
"src/client/voice/player/AudioPlayer.js": false,
"src/client/voice/player/BasePlayer.js": false,
"src/client/voice/player/BroadcastAudioPlayer.js": false,
"src/client/voice/receiver/PacketHandler.js": false,
"src/client/voice/receiver/Receiver.js": false,
"src/client/voice/util/PlayInterface.js": false,
"src/client/voice/util/Secretbox.js": false,
"src/client/voice/util/Silence.js": false,
"src/client/voice/util/VolumeInterface.js": false
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.js": "eslint --fix",
"*.ts": "prettier --write"
},
"commitlint": {
"extends": [
"@commitlint/config-angular"
],
"rules": {
"scope-case": [
2,
"always",
"pascal-case"
],
"type-enum": [
2,
"always",
[
"chore",
"build",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
"test"
]
]
}
},
"prettier": {
"singleQuote": true,
"printWidth": 120,
"trailingComma": "all",
"endOfLine": "lf",
"arrowParens": "avoid"
}
}

49
src/WebSocket.js Normal file
View File

@@ -0,0 +1,49 @@
'use strict';
const { browser } = require('./util/Constants');
let erlpack;
try {
erlpack = require('erlpack');
if (!erlpack.pack) erlpack = null;
} catch {} // eslint-disable-line no-empty
let TextDecoder;
if (browser) {
TextDecoder = window.TextDecoder; // eslint-disable-line no-undef
exports.WebSocket = window.WebSocket; // eslint-disable-line no-undef
} else {
TextDecoder = require('util').TextDecoder;
exports.WebSocket = require('ws');
}
const ab = new TextDecoder();
exports.encoding = erlpack ? 'etf' : 'json';
exports.pack = erlpack ? erlpack.pack : JSON.stringify;
exports.unpack = (data, type) => {
if (exports.encoding === 'json' || type === 'json') {
if (typeof data !== 'string') {
data = ab.decode(data);
}
return JSON.parse(data);
}
if (!Buffer.isBuffer(data)) data = Buffer.from(new Uint8Array(data));
return erlpack.unpack(data);
};
exports.create = (gateway, query = {}, ...args) => {
const [g, q] = gateway.split('?');
query.encoding = exports.encoding;
query = new URLSearchParams(query);
if (q) new URLSearchParams(q).forEach((v, k) => query.set(k, v));
const ws = new exports.WebSocket(`${g}?${query}`, ...args);
if (browser) ws.binaryType = 'arraybuffer';
return ws;
};
for (const state of ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']) exports[state] = exports.WebSocket[state];

169
src/client/BaseClient.js Normal file
View File

@@ -0,0 +1,169 @@
'use strict';
require('setimmediate');
const EventEmitter = require('events');
const RESTManager = require('../rest/RESTManager');
const { DefaultOptions } = require('../util/Constants');
const Util = require('../util/Util');
/**
* The base class for all clients.
* @extends {EventEmitter}
*/
class BaseClient extends EventEmitter {
constructor(options = {}) {
super();
/**
* Timeouts set by {@link BaseClient#setTimeout} that are still active
* @type {Set<Timeout>}
* @private
*/
this._timeouts = new Set();
/**
* Intervals set by {@link BaseClient#setInterval} that are still active
* @type {Set<Timeout>}
* @private
*/
this._intervals = new Set();
/**
* Intervals set by {@link BaseClient#setImmediate} that are still active
* @type {Set<Immediate>}
* @private
*/
this._immediates = new Set();
/**
* The options the client was instantiated with
* @type {ClientOptions}
*/
this.options = Util.mergeDefault(DefaultOptions, options);
/**
* The REST manager of the client
* @type {RESTManager}
* @private
*/
this.rest = new RESTManager(this, options._tokenType);
}
/**
* API shortcut
* @type {Object}
* @readonly
* @private
*/
get api() {
return this.rest.api;
}
/**
* Destroys all assets used by the base client.
*/
destroy() {
for (const t of this._timeouts) this.clearTimeout(t);
for (const i of this._intervals) this.clearInterval(i);
for (const i of this._immediates) this.clearImmediate(i);
this._timeouts.clear();
this._intervals.clear();
this._immediates.clear();
}
/**
* Sets a timeout that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setTimeout(fn, delay, ...args) {
const timeout = setTimeout(() => {
fn(...args);
this._timeouts.delete(timeout);
}, delay);
this._timeouts.add(timeout);
return timeout;
}
/**
* Clears a timeout.
* @param {Timeout} timeout Timeout to cancel
*/
clearTimeout(timeout) {
clearTimeout(timeout);
this._timeouts.delete(timeout);
}
/**
* Sets an interval that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait between executions (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setInterval(fn, delay, ...args) {
const interval = setInterval(fn, delay, ...args);
this._intervals.add(interval);
return interval;
}
/**
* Clears an interval.
* @param {Timeout} interval Interval to cancel
*/
clearInterval(interval) {
clearInterval(interval);
this._intervals.delete(interval);
}
/**
* Sets an immediate that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {...*} args Arguments for the function
* @returns {Immediate}
*/
setImmediate(fn, ...args) {
const immediate = setImmediate(fn, ...args);
this._immediates.add(immediate);
return immediate;
}
/**
* Clears an immediate.
* @param {Immediate} immediate Immediate to cancel
*/
clearImmediate(immediate) {
clearImmediate(immediate);
this._immediates.delete(immediate);
}
/**
* Increments max listeners by one, if they are not zero.
* @private
*/
incrementMaxListeners() {
const maxListeners = this.getMaxListeners();
if (maxListeners !== 0) {
this.setMaxListeners(maxListeners + 1);
}
}
/**
* Decrements max listeners by one, if they are not zero.
* @private
*/
decrementMaxListeners() {
const maxListeners = this.getMaxListeners();
if (maxListeners !== 0) {
this.setMaxListeners(maxListeners - 1);
}
}
toJSON(...props) {
return Util.flatten(this, { domain: false }, ...props);
}
}
module.exports = BaseClient;

View File

@@ -1,76 +1,86 @@
const EventEmitter = require('events');
const Constants = require('../util/Constants');
const Permissions = require('../util/Permissions');
const Util = require('../util/Util');
const RESTManager = require('./rest/RESTManager');
const ClientDataManager = require('./ClientDataManager');
const ClientManager = require('./ClientManager');
const ClientDataResolver = require('./ClientDataResolver');
'use strict';
const BaseClient = require('./BaseClient');
const ActionsManager = require('./actions/ActionsManager');
const ClientVoiceManager = require('./voice/ClientVoiceManager');
const WebSocketManager = require('./websocket/WebSocketManager');
const ActionsManager = require('./actions/ActionsManager');
const Collection = require('../util/Collection');
const Presence = require('../structures/Presence').Presence;
const { Error, TypeError, RangeError } = require('../errors');
const ChannelManager = require('../managers/ChannelManager');
const GuildEmojiManager = require('../managers/GuildEmojiManager');
const GuildManager = require('../managers/GuildManager');
const UserManager = require('../managers/UserManager');
const ShardClientUtil = require('../sharding/ShardClientUtil');
const VoiceBroadcast = require('./voice/VoiceBroadcast');
const ClientApplication = require('../structures/ClientApplication');
const GuildPreview = require('../structures/GuildPreview');
const GuildTemplate = require('../structures/GuildTemplate');
const Invite = require('../structures/Invite');
const VoiceRegion = require('../structures/VoiceRegion');
const Webhook = require('../structures/Webhook');
const Collection = require('../util/Collection');
const { Events, browser, DefaultOptions } = require('../util/Constants');
const DataResolver = require('../util/DataResolver');
const Intents = require('../util/Intents');
const Permissions = require('../util/Permissions');
const Structures = require('../util/Structures');
/**
* The main hub for interacting with the Discord API, and the starting point for any bot.
* @extends {EventEmitter}
* @extends {BaseClient}
*/
class Client extends EventEmitter {
class Client extends BaseClient {
/**
* @param {ClientOptions} [options] Options for the client
*/
constructor(options = {}) {
super();
super(Object.assign({ _tokenType: 'Bot' }, options));
// Obtain shard details from environment
if (!options.shardId && 'SHARD_ID' in process.env) options.shardId = Number(process.env.SHARD_ID);
if (!options.shardCount && 'SHARD_COUNT' in process.env) options.shardCount = Number(process.env.SHARD_COUNT);
// Obtain shard details from environment or if present, worker threads
let data = process.env;
try {
// Test if worker threads module is present and used
data = require('worker_threads').workerData || data;
} catch {
// Do nothing
}
if (this.options.shards === DefaultOptions.shards) {
if ('SHARDS' in data) {
this.options.shards = JSON.parse(data.SHARDS);
}
}
if (this.options.shardCount === DefaultOptions.shardCount) {
if ('SHARD_COUNT' in data) {
this.options.shardCount = Number(data.SHARD_COUNT);
} else if (Array.isArray(this.options.shards)) {
this.options.shardCount = this.options.shards.length;
}
}
const typeofShards = typeof this.options.shards;
if (typeofShards === 'undefined' && typeof this.options.shardCount === 'number') {
this.options.shards = Array.from({ length: this.options.shardCount }, (_, i) => i);
}
if (typeofShards === 'number') this.options.shards = [this.options.shards];
if (Array.isArray(this.options.shards)) {
this.options.shards = [
...new Set(
this.options.shards.filter(item => !isNaN(item) && item >= 0 && item < Infinity && item === (item | 0)),
),
];
}
/**
* The options the client was instantiated with
* @type {ClientOptions}
*/
this.options = Util.mergeDefault(Constants.DefaultOptions, options);
this._validateOptions();
/**
* The REST manager of the client
* @type {RESTManager}
* @private
*/
this.rest = new RESTManager(this);
/**
* The data manager of the client
* @type {ClientDataManager}
* @private
*/
this.dataManager = new ClientDataManager(this);
/**
* The manager of the client
* @type {ClientManager}
* @private
*/
this.manager = new ClientManager(this);
/**
* The WebSocket manager of the client
* @type {WebSocketManager}
* @private
*/
this.ws = new WebSocketManager(this);
/**
* The data resolver of the client
* @type {ClientDataResolver}
* @private
*/
this.resolver = new ClientDataResolver(this);
/**
* The action manager of the client
* @type {ActionsManager}
@@ -81,52 +91,57 @@ class Client extends EventEmitter {
/**
* The voice manager of the client (`null` in browsers)
* @type {?ClientVoiceManager}
* @private
*/
this.voice = !this.browser ? new ClientVoiceManager(this) : null;
this.voice = !browser ? new ClientVoiceManager(this) : null;
/**
* The shard helpers for the client
* (only if the process was spawned as a child, such as from a {@link ShardingManager})
* Shard helpers for the client (only if the process was spawned from a {@link ShardingManager})
* @type {?ShardClientUtil}
*/
this.shard = process.send ? ShardClientUtil.singleton(this) : null;
this.shard =
!browser && process.env.SHARDING_MANAGER
? ShardClientUtil.singleton(this, process.env.SHARDING_MANAGER_MODE)
: null;
/**
* All of the {@link User} objects that have been cached at any point, mapped by their IDs
* @type {Collection<Snowflake, User>}
* @type {UserManager}
*/
this.users = new Collection();
this.users = new UserManager(this);
/**
* All of the guilds the client is currently handling, mapped by their IDs -
* as long as sharding isn't being used, this will be *every* guild the bot is a member of
* @type {Collection<Snowflake, Guild>}
* @type {GuildManager}
*/
this.guilds = new Collection();
this.guilds = new GuildManager(this);
/**
* All of the {@link Channel}s that the client is currently handling, mapped by their IDs -
* as long as sharding isn't being used, this will be *every* channel in *every* guild, and all DM channels
* @type {Collection<Snowflake, Channel>}
* as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
* is a member of. Note that DM channels will not be initially cached, and thus not be present
* in the Manager without their explicit fetching or use.
* @type {ChannelManager}
*/
this.channels = new Collection();
this.channels = new ChannelManager(this);
const ClientPresence = Structures.get('ClientPresence');
/**
* Presences that have been received for the client user's friends, mapped by user IDs
* <warn>This is only filled when using a user account.</warn>
* @type {Collection<Snowflake, Presence>}
* The presence of the Client
* @private
* @type {ClientPresence}
*/
this.presences = new Collection();
this.presence = new ClientPresence(this);
Object.defineProperty(this, 'token', { writable: true });
if (!this.token && 'CLIENT_TOKEN' in process.env) {
if (!browser && !this.token && 'DISCORD_TOKEN' in process.env) {
/**
* Authorization token for the logged in user/bot
* Authorization token for the logged in bot.
* If present, this defaults to `process.env.DISCORD_TOKEN` when instantiating the client
* <warn>This should be kept private at all times.</warn>
* @type {?string}
*/
this.token = process.env.CLIENT_TOKEN;
this.token = process.env.DISCORD_TOKEN;
} else {
this.token = null;
}
@@ -144,92 +159,20 @@ class Client extends EventEmitter {
*/
this.readyAt = null;
/**
* Active voice broadcasts that have been created
* @type {VoiceBroadcast[]}
*/
this.broadcasts = [];
/**
* Previous heartbeat pings of the websocket (most recent first, limited to three elements)
* @type {number[]}
*/
this.pings = [];
/**
* Timeouts set by {@link Client#setTimeout} that are still active
* @type {Set<Timeout>}
* @private
*/
this._timeouts = new Set();
/**
* Intervals set by {@link Client#setInterval} that are still active
* @type {Set<Timeout>}
* @private
*/
this._intervals = new Set();
if (this.options.messageSweepInterval > 0) {
this.setInterval(this.sweepMessages.bind(this), this.options.messageSweepInterval * 1000);
}
}
/**
* Timestamp of the latest ping's start time
* @type {number}
* @private
*/
get _pingTimestamp() {
return this.ws.connection ? this.ws.connection.lastPingTimestamp : 0;
}
/**
* Current status of the client's connection to Discord
* @type {?number}
* @readonly
*/
get status() {
return this.ws.connection.status;
}
/**
* How long it has been since the client last entered the `READY` state in milliseconds
* @type {?number}
* @readonly
*/
get uptime() {
return this.readyAt ? Date.now() - this.readyAt : null;
}
/**
* Average heartbeat ping of the websocket, obtained by averaging the {@link Client#pings} property
* @type {number}
* @readonly
*/
get ping() {
return this.pings.reduce((prev, p) => prev + p, 0) / this.pings.length;
}
/**
* All active voice connections that have been established, mapped by guild ID
* @type {Collection<Snowflake, VoiceConnection>}
* @readonly
*/
get voiceConnections() {
if (this.browser) return new Collection();
return this.voice.connections;
}
/**
* All custom emojis that the client has access to, mapped by their IDs
* @type {Collection<Snowflake, Emoji>}
* @type {GuildEmojiManager}
* @readonly
*/
get emojis() {
const emojis = new Collection();
for (const guild of this.guilds.values()) {
for (const emoji of guild.emojis.values()) emojis.set(emoji.id, emoji);
const emojis = new GuildEmojiManager({ client: this });
for (const guild of this.guilds.cache.values()) {
if (guild.available) for (const emoji of guild.emojis.cache.values()) emojis.cache.set(emoji.id, emoji);
}
return emojis;
}
@@ -244,85 +187,89 @@ class Client extends EventEmitter {
}
/**
* Whether the client is in a browser environment
* @type {boolean}
* How long it has been since the client last entered the `READY` state in milliseconds
* @type {?number}
* @readonly
*/
get browser() {
return typeof window !== 'undefined';
}
/**
* Creates a voice broadcast.
* @returns {VoiceBroadcast}
*/
createVoiceBroadcast() {
const broadcast = new VoiceBroadcast(this);
this.broadcasts.push(broadcast);
return broadcast;
get uptime() {
return this.readyAt ? Date.now() - this.readyAt : null;
}
/**
* Logs the client in, establishing a websocket connection to Discord.
* <info>Both bot and regular user accounts are supported, but it is highly recommended to use a bot account whenever
* possible. User accounts are subject to harsher ratelimits and other restrictions that don't apply to bot accounts.
* Bot accounts also have access to many features that user accounts cannot utilise. User accounts that are found to
* be abusing/overusing the API will be banned, locking you out of Discord entirely.</info>
* @param {string} token Token of the account to log in with
* @param {string} [token=this.token] Token of the account to log in with
* @returns {Promise<string>} Token of the account used
* @example
* client.login('my token');
*/
login(token) {
return this.rest.methods.login(token);
async login(token = this.token) {
if (!token || typeof token !== 'string') throw new Error('TOKEN_INVALID');
this.token = token = token.replace(/^(Bot|Bearer)\s*/i, '');
this.emit(
Events.DEBUG,
`Provided token: ${token
.split('.')
.map((val, i) => (i > 1 ? val.replace(/./g, '*') : val))
.join('.')}`,
);
if (this.options.presence) {
this.options.ws.presence = await this.presence._parse(this.options.presence);
}
this.emit(Events.DEBUG, 'Preparing to connect to the gateway...');
try {
await this.ws.connect();
return this.token;
} catch (error) {
this.destroy();
throw error;
}
}
/**
* Logs out, terminates the connection to Discord, and destroys the client.
* @returns {Promise}
* @returns {void}
*/
destroy() {
for (const t of this._timeouts) clearTimeout(t);
for (const i of this._intervals) clearInterval(i);
this._timeouts.clear();
this._intervals.clear();
return this.manager.destroy();
}
/**
* Requests a sync of guild data with Discord.
* <info>This can be done automatically every 30 seconds by enabling {@link ClientOptions#sync}.</info>
* <warn>This is only available when using a user account.</warn>
* @param {Guild[]|Collection<Snowflake, Guild>} [guilds=this.guilds] An array or collection of guilds to sync
*/
syncGuilds(guilds = this.guilds) {
if (this.user.bot) return;
this.ws.send({
op: 12,
d: guilds instanceof Collection ? guilds.keyArray() : guilds.map(g => g.id),
});
}
/**
* Obtains a user from Discord, or the user cache if it's already available.
* <warn>This is only available when using a bot account.</warn>
* @param {Snowflake} id ID of the user
* @param {boolean} [cache=true] Whether to cache the new user object if it isn't already
* @returns {Promise<User>}
*/
fetchUser(id, cache = true) {
if (this.users.has(id)) return Promise.resolve(this.users.get(id));
return this.rest.methods.getUser(id, cache);
super.destroy();
this.ws.destroy();
this.token = null;
}
/**
* Obtains an invite from Discord.
* @param {InviteResolvable} invite Invite code or URL
* @returns {Promise<Invite>}
* @example
* client.fetchInvite('https://discord.gg/bRCvFy9')
* .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
* .catch(console.error);
*/
fetchInvite(invite) {
const code = this.resolver.resolveInviteCode(invite);
return this.rest.methods.getInvite(code);
const code = DataResolver.resolveInviteCode(invite);
return this.api
.invites(code)
.get({ query: { with_counts: true } })
.then(data => new Invite(this, data));
}
/**
* Obtains a template from Discord.
* @param {GuildTemplateResolvable} template Template code or URL
* @returns {Promise<GuildTemplate>}
* @example
* client.fetchGuildTemplate('https://discord.new/FKvmczH2HyUf')
* .then(template => console.log(`Obtained template with code: ${template.code}`))
* .catch(console.error);
*/
fetchGuildTemplate(template) {
const code = DataResolver.resolveGuildTemplateCode(template);
return this.api.guilds
.templates(code)
.get()
.then(data => new GuildTemplate(this, data));
}
/**
@@ -330,17 +277,32 @@ class Client extends EventEmitter {
* @param {Snowflake} id ID of the webhook
* @param {string} [token] Token for the webhook
* @returns {Promise<Webhook>}
* @example
* client.fetchWebhook('id', 'token')
* .then(webhook => console.log(`Obtained webhook with name: ${webhook.name}`))
* .catch(console.error);
*/
fetchWebhook(id, token) {
return this.rest.methods.getWebhook(id, token);
return this.api
.webhooks(id, token)
.get()
.then(data => new Webhook(this, data));
}
/**
* Obtains the available voice regions from Discord.
* @returns {Collection<string, VoiceRegion>}
* @returns {Promise<Collection<string, VoiceRegion>>}
* @example
* client.fetchVoiceRegions()
* .then(regions => console.log(`Available regions are: ${regions.map(region => region.name).join(', ')}`))
* .catch(console.error);
*/
fetchVoiceRegions() {
return this.rest.methods.fetchVoiceRegions();
return this.api.voice.regions.get().then(res => {
const regions = new Collection();
for (const region of res) regions.set(region.id, new VoiceRegion(region));
return regions;
});
}
/**
@@ -350,11 +312,17 @@ class Client extends EventEmitter {
* will be removed from the caches. The default is based on {@link ClientOptions#messageCacheLifetime}
* @returns {number} Amount of messages that were removed from the caches,
* or -1 if the message cache lifetime is unlimited
* @example
* // Remove all messages older than 1800 seconds from the messages cache
* const amount = client.sweepMessages(1800);
* console.log(`Successfully removed ${amount} messages from the cache.`);
*/
sweepMessages(lifetime = this.options.messageCacheLifetime) {
if (typeof lifetime !== 'number' || isNaN(lifetime)) throw new TypeError('The lifetime must be a number.');
if (typeof lifetime !== 'number' || isNaN(lifetime)) {
throw new TypeError('INVALID_TYPE', 'lifetime', 'number');
}
if (lifetime <= 0) {
this.emit('debug', 'Didn\'t sweep messages - lifetime is unlimited');
this.emit(Events.DEBUG, "Didn't sweep messages - lifetime is unlimited");
return -1;
}
@@ -363,123 +331,87 @@ class Client extends EventEmitter {
let channels = 0;
let messages = 0;
for (const channel of this.channels.values()) {
for (const channel of this.channels.cache.values()) {
if (!channel.messages) continue;
channels++;
for (const message of channel.messages.values()) {
if (now - (message.editedTimestamp || message.createdTimestamp) > lifetimeMs) {
channel.messages.delete(message.id);
messages++;
}
}
messages += channel.messages.cache.sweep(
message => now - (message.editedTimestamp || message.createdTimestamp) > lifetimeMs,
);
}
this.emit('debug', `Swept ${messages} messages older than ${lifetime} seconds in ${channels} text-based channels`);
this.emit(
Events.DEBUG,
`Swept ${messages} messages older than ${lifetime} seconds in ${channels} text-based channels`,
);
return messages;
}
/**
* Obtains the OAuth Application of the bot from Discord.
* @param {Snowflake} [id='@me'] ID of application to fetch
* @returns {Promise<OAuth2Application>}
* Obtains the OAuth Application of this bot from Discord.
* @returns {Promise<ClientApplication>}
*/
fetchApplication(id = '@me') {
return this.rest.methods.getApplication(id);
fetchApplication() {
return this.api.oauth2
.applications('@me')
.get()
.then(app => new ClientApplication(this, app));
}
/**
* Obtains a guild preview from Discord, available for all guilds the bot is in and all Discoverable guilds.
* @param {GuildResolvable} guild The guild to fetch the preview for
* @returns {Promise<GuildPreview>}
*/
fetchGuildPreview(guild) {
const id = this.guilds.resolveID(guild);
if (!id) throw new TypeError('INVALID_TYPE', 'guild', 'GuildResolvable');
return this.api
.guilds(id)
.preview.get()
.then(data => new GuildPreview(this, data));
}
/**
* Generates a link that can be used to invite the bot to a guild.
* <warn>This is only available when using a bot account.</warn>
* @param {PermissionResolvable[]|number} [permissions] Permissions to request
* @param {InviteGenerationOptions|PermissionResolvable} [options] Permissions to request
* @returns {Promise<string>}
* @example
* client.generateInvite(['SEND_MESSAGES', 'MANAGE_GUILD', 'MENTION_EVERYONE'])
* .then(link => {
* console.log(`Generated bot invite link: ${link}`);
* });
* client.generateInvite({
* permissions: ['SEND_MESSAGES', 'MANAGE_GUILD', 'MENTION_EVERYONE'],
* })
* .then(link => console.log(`Generated bot invite link: ${link}`))
* .catch(console.error);
*/
generateInvite(permissions) {
if (permissions) {
if (permissions instanceof Array) permissions = Permissions.resolve(permissions);
} else {
permissions = 0;
async generateInvite(options = {}) {
if (Array.isArray(options) || ['string', 'number'].includes(typeof options) || options instanceof Permissions) {
process.emitWarning(
'Client#generateInvite: Generate invite with an options object instead of a PermissionResolvable',
'DeprecationWarning',
);
options = { permissions: options };
}
return this.fetchApplication().then(application =>
`https://discordapp.com/oauth2/authorize?client_id=${application.id}&permissions=${permissions}&scope=bot`
);
}
/**
* Sets a timeout that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setTimeout(fn, delay, ...args) {
const timeout = setTimeout(() => {
fn(...args);
this._timeouts.delete(timeout);
}, delay);
this._timeouts.add(timeout);
return timeout;
}
/**
* Clears a timeout.
* @param {Timeout} timeout Timeout to cancel
*/
clearTimeout(timeout) {
clearTimeout(timeout);
this._timeouts.delete(timeout);
}
/**
* Sets an interval that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setInterval(fn, delay, ...args) {
const interval = setInterval(fn, delay, ...args);
this._intervals.add(interval);
return interval;
}
/**
* Clears an interval.
* @param {Timeout} interval Interval to cancel
*/
clearInterval(interval) {
clearInterval(interval);
this._intervals.delete(interval);
}
/**
* Adds a ping to {@link Client#pings}.
* @param {number} startTime Starting time of the ping
* @private
*/
_pong(startTime) {
this.pings.unshift(Date.now() - startTime);
if (this.pings.length > 3) this.pings.length = 3;
this.ws.lastHeartbeatAck = true;
}
/**
* Adds/updates a friend's presence in {@link Client#presences}.
* @param {Snowflake} id ID of the user
* @param {Object} presence Raw presence object from Discord
* @private
*/
_setPresence(id, presence) {
if (this.presences.has(id)) {
this.presences.get(id).update(presence);
return;
const application = await this.fetchApplication();
const query = new URLSearchParams({
client_id: application.id,
permissions: Permissions.resolve(options.permissions),
scope: 'bot',
});
if (typeof options.disableGuildSelect === 'boolean') {
query.set('disable_guild_select', options.disableGuildSelect.toString());
}
this.presences.set(id, new Presence(presence));
if (typeof options.guild !== 'undefined') {
const guildID = this.guilds.resolveID(options.guild);
if (!guildID) throw new TypeError('INVALID_TYPE', 'options.guild', 'GuildResolvable');
query.set('guild_id', guildID);
}
return `${this.options.http.api}${this.api.oauth2.authorize}?${query}`;
}
toJSON() {
return super.toJSON({
readyAt: false,
});
}
/**
@@ -499,41 +431,66 @@ class Client extends EventEmitter {
* @private
*/
_validateOptions(options = this.options) {
if (typeof options.shardCount !== 'number' || isNaN(options.shardCount)) {
throw new TypeError('The shardCount option must be a number.');
if (typeof options.ws.intents !== 'undefined') {
options.ws.intents = Intents.resolve(options.ws.intents);
}
if (typeof options.shardId !== 'number' || isNaN(options.shardId)) {
throw new TypeError('The shardId option must be a number.');
if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) {
throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number greater than or equal to 1');
}
if (options.shardCount < 0) throw new RangeError('The shardCount option must be at least 0.');
if (options.shardId < 0) throw new RangeError('The shardId option must be at least 0.');
if (options.shardId !== 0 && options.shardId >= options.shardCount) {
throw new RangeError('The shardId option must be less than shardCount.');
if (options.shards && !(options.shards === 'auto' || Array.isArray(options.shards))) {
throw new TypeError('CLIENT_INVALID_OPTION', 'shards', "'auto', a number or array of numbers");
}
if (options.shards && !options.shards.length) throw new RangeError('CLIENT_INVALID_PROVIDED_SHARDS');
if (typeof options.messageCacheMaxSize !== 'number' || isNaN(options.messageCacheMaxSize)) {
throw new TypeError('The messageCacheMaxSize option must be a number.');
throw new TypeError('CLIENT_INVALID_OPTION', 'messageCacheMaxSize', 'a number');
}
if (typeof options.messageCacheLifetime !== 'number' || isNaN(options.messageCacheLifetime)) {
throw new TypeError('The messageCacheLifetime option must be a number.');
throw new TypeError('CLIENT_INVALID_OPTION', 'The messageCacheLifetime', 'a number');
}
if (typeof options.messageSweepInterval !== 'number' || isNaN(options.messageSweepInterval)) {
throw new TypeError('The messageSweepInterval option must be a number.');
throw new TypeError('CLIENT_INVALID_OPTION', 'messageSweepInterval', 'a number');
}
if (
typeof options.messageEditHistoryMaxSize !== 'number' ||
isNaN(options.messageEditHistoryMaxSize) ||
options.messageEditHistoryMaxSize < -1
) {
throw new TypeError('CLIENT_INVALID_OPTION', 'messageEditHistoryMaxSize', 'a number greater than or equal to -1');
}
if (typeof options.fetchAllMembers !== 'boolean') {
throw new TypeError('The fetchAllMembers option must be a boolean.');
throw new TypeError('CLIENT_INVALID_OPTION', 'fetchAllMembers', 'a boolean');
}
if (typeof options.disableEveryone !== 'boolean') {
throw new TypeError('The disableEveryone option must be a boolean.');
if (typeof options.disableMentions !== 'string') {
throw new TypeError('CLIENT_INVALID_OPTION', 'disableMentions', 'a string');
}
if (!Array.isArray(options.partials)) {
throw new TypeError('CLIENT_INVALID_OPTION', 'partials', 'an Array');
}
if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) {
throw new TypeError('The restWsBridgeTimeout option must be a number.');
throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number');
}
if (typeof options.restRequestTimeout !== 'number' || isNaN(options.restRequestTimeout)) {
throw new TypeError('CLIENT_INVALID_OPTION', 'restRequestTimeout', 'a number');
}
if (typeof options.restSweepInterval !== 'number' || isNaN(options.restSweepInterval)) {
throw new TypeError('CLIENT_INVALID_OPTION', 'restSweepInterval', 'a number');
}
if (typeof options.retryLimit !== 'number' || isNaN(options.retryLimit)) {
throw new TypeError('CLIENT_INVALID_OPTION', 'retryLimit', 'a number');
}
if (!(options.disabledEvents instanceof Array)) throw new TypeError('The disabledEvents option must be an Array.');
}
}
module.exports = Client;
/**
* Options for {@link Client#generateInvite}.
* @typedef {Object} InviteGenerationOptions
* @property {PermissionResolvable} [permissions] Permissions to request
* @property {GuildResolvable} [guild] Guild to preselect
* @property {boolean} [disableGuildSelect] Whether to disable the guild selection
*/
/**
* Emitted for general warnings.
* @event Client#warn

View File

@@ -1,136 +0,0 @@
const Constants = require('../util/Constants');
const Util = require('../util/Util');
const Guild = require('../structures/Guild');
const User = require('../structures/User');
const CategoryChannel = require('../structures/CategoryChannel');
const DMChannel = require('../structures/DMChannel');
const Emoji = require('../structures/Emoji');
const TextChannel = require('../structures/TextChannel');
const VoiceChannel = require('../structures/VoiceChannel');
const GuildChannel = require('../structures/GuildChannel');
const GroupDMChannel = require('../structures/GroupDMChannel');
class ClientDataManager {
constructor(client) {
this.client = client;
}
get pastReady() {
return this.client.ws.connection.status === Constants.Status.READY;
}
newGuild(data) {
const already = this.client.guilds.has(data.id);
const guild = new Guild(this.client, data);
this.client.guilds.set(guild.id, guild);
if (this.pastReady && !already) {
/**
* Emitted whenever the client joins a guild.
* @event Client#guildCreate
* @param {Guild} guild The created guild
*/
if (this.client.options.fetchAllMembers) {
guild.fetchMembers().then(() => { this.client.emit(Constants.Events.GUILD_CREATE, guild); });
} else {
this.client.emit(Constants.Events.GUILD_CREATE, guild);
}
}
return guild;
}
newUser(data) {
if (this.client.users.has(data.id)) return this.client.users.get(data.id);
const user = new User(this.client, data);
this.client.users.set(user.id, user);
return user;
}
newChannel(data, guild) {
const already = this.client.channels.has(data.id);
let channel;
if (data.type === Constants.ChannelTypes.DM) {
channel = new DMChannel(this.client, data);
} else if (data.type === Constants.ChannelTypes.GROUP_DM) {
channel = new GroupDMChannel(this.client, data);
} else {
guild = guild || this.client.guilds.get(data.guild_id);
if (guild) {
if (data.type === Constants.ChannelTypes.TEXT) {
channel = new TextChannel(guild, data);
guild.channels.set(channel.id, channel);
} else if (data.type === Constants.ChannelTypes.VOICE) {
channel = new VoiceChannel(guild, data);
guild.channels.set(channel.id, channel);
} else if (data.type === Constants.ChannelTypes.CATEGORY) {
channel = new CategoryChannel(guild, data);
guild.channels.set(channel.id, channel);
}
}
}
if (channel && !already) {
if (this.pastReady) this.client.emit(Constants.Events.CHANNEL_CREATE, channel);
this.client.channels.set(channel.id, channel);
return channel;
} else if (already) {
return channel;
}
return null;
}
newEmoji(data, guild) {
const already = guild.emojis.has(data.id);
if (data && !already) {
let emoji = new Emoji(guild, data);
this.client.emit(Constants.Events.GUILD_EMOJI_CREATE, emoji);
guild.emojis.set(emoji.id, emoji);
return emoji;
} else if (already) {
return guild.emojis.get(data.id);
}
return null;
}
killEmoji(emoji) {
if (!(emoji instanceof Emoji && emoji.guild)) return;
this.client.emit(Constants.Events.GUILD_EMOJI_DELETE, emoji);
emoji.guild.emojis.delete(emoji.id);
}
killGuild(guild) {
const already = this.client.guilds.has(guild.id);
this.client.guilds.delete(guild.id);
if (already && this.pastReady) this.client.emit(Constants.Events.GUILD_DELETE, guild);
}
killUser(user) {
this.client.users.delete(user.id);
}
killChannel(channel) {
this.client.channels.delete(channel.id);
if (channel instanceof GuildChannel) channel.guild.channels.delete(channel.id);
}
updateGuild(currentGuild, newData) {
const oldGuild = Util.cloneObject(currentGuild);
currentGuild.setup(newData);
if (this.pastReady) this.client.emit(Constants.Events.GUILD_UPDATE, oldGuild, currentGuild);
}
updateChannel(currentChannel, newData) {
currentChannel.setup(newData);
}
updateEmoji(currentEmoji, newData) {
const oldEmoji = Util.cloneObject(currentEmoji);
currentEmoji.setup(newData);
this.client.emit(Constants.Events.GUILD_EMOJI_UPDATE, oldEmoji, currentEmoji);
return currentEmoji;
}
}
module.exports = ClientDataManager;

View File

@@ -1,378 +0,0 @@
const path = require('path');
const fs = require('fs');
const snekfetch = require('snekfetch');
const Constants = require('../util/Constants');
const convertToBuffer = require('../util/Util').convertToBuffer;
const User = require('../structures/User');
const Message = require('../structures/Message');
const Guild = require('../structures/Guild');
const Channel = require('../structures/Channel');
const GuildMember = require('../structures/GuildMember');
const Emoji = require('../structures/Emoji');
const ReactionEmoji = require('../structures/ReactionEmoji');
const Role = require('../structures/Role');
/**
* The DataResolver identifies different objects and tries to resolve a specific piece of information from them, e.g.
* extracting a User from a Message object.
* @private
*/
class ClientDataResolver {
/**
* @param {Client} client The client the resolver is for
*/
constructor(client) {
this.client = client;
}
/**
* Data that resolves to give a User object. This can be:
* * A User object
* * A Snowflake
* * A Message object (resolves to the message author)
* * A Guild object (owner of the guild)
* * A GuildMember object
* @typedef {User|Snowflake|Message|Guild|GuildMember} UserResolvable
*/
/**
* Resolves a UserResolvable to a User object.
* @param {UserResolvable} user The UserResolvable to identify
* @returns {?User}
*/
resolveUser(user) {
if (user instanceof User) return user;
if (typeof user === 'string') return this.client.users.get(user) || null;
if (user instanceof GuildMember) return user.user;
if (user instanceof Message) return user.author;
if (user instanceof Guild) return user.owner;
return null;
}
/**
* Resolves a UserResolvable to a user ID string.
* @param {UserResolvable} user The UserResolvable to identify
* @returns {?Snowflake}
*/
resolveUserID(user) {
if (user instanceof User || user instanceof GuildMember) return user.id;
if (typeof user === 'string') return user || null;
if (user instanceof Message) return user.author.id;
if (user instanceof Guild) return user.ownerID;
return null;
}
/**
* Data that resolves to give a Guild object. This can be:
* * A Guild object
* * A Snowflake
* @typedef {Guild|Snowflake} GuildResolvable
*/
/**
* Resolves a GuildResolvable to a Guild object.
* @param {GuildResolvable} guild The GuildResolvable to identify
* @returns {?Guild}
*/
resolveGuild(guild) {
if (guild instanceof Guild) return guild;
if (typeof guild === 'string') return this.client.guilds.get(guild) || null;
return null;
}
/**
* Data that resolves to give a GuildMember object. This can be:
* * A GuildMember object
* * A User object
* @typedef {GuildMember|User} GuildMemberResolvable
*/
/**
* Resolves a GuildMemberResolvable to a GuildMember object.
* @param {GuildResolvable} guild The guild that the member is part of
* @param {UserResolvable} user The user that is part of the guild
* @returns {?GuildMember}
*/
resolveGuildMember(guild, user) {
if (user instanceof GuildMember) return user;
guild = this.resolveGuild(guild);
user = this.resolveUser(user);
if (!guild || !user) return null;
return guild.members.get(user.id) || null;
}
/**
* Data that can be resolved to a Role object. This can be:
* * A Role
* * A Snowflake
* @typedef {Role|Snowflake} RoleResolvable
*/
/**
* Resolves a RoleResolvable to a Role object.
* @param {GuildResolvable} guild The guild that this role is part of
* @param {RoleResolvable} role The role resolvable to resolve
* @returns {?Role}
*/
resolveRole(guild, role) {
if (role instanceof Role) return role;
guild = this.resolveGuild(guild);
if (!guild) return null;
if (typeof role === 'string') return guild.roles.get(role);
return null;
}
/**
* Data that can be resolved to give a Channel object. This can be:
* * A Channel object
* * A Message object (the channel the message was sent in)
* * A Guild object (the #general channel)
* * A Snowflake
* @typedef {Channel|Guild|Message|Snowflake} ChannelResolvable
*/
/**
* Resolves a ChannelResolvable to a Channel object.
* @param {ChannelResolvable} channel The channel resolvable to resolve
* @returns {?Channel}
*/
resolveChannel(channel) {
if (channel instanceof Channel) return channel;
if (typeof channel === 'string') return this.client.channels.get(channel) || null;
if (channel instanceof Message) return channel.channel;
if (channel instanceof Guild) return channel.channels.get(channel.id) || null;
return null;
}
/**
* Resolves a ChannelResolvable to a channel ID.
* @param {ChannelResolvable} channel The channel resolvable to resolve
* @returns {?Snowflake}
*/
resolveChannelID(channel) {
if (channel instanceof Channel) return channel.id;
if (typeof channel === 'string') return channel;
if (channel instanceof Message) return channel.channel.id;
if (channel instanceof Guild) return channel.defaultChannel.id;
return null;
}
/**
* Data that can be resolved to give an invite code. This can be:
* * An invite code
* * An invite URL
* @typedef {string} InviteResolvable
*/
/**
* Resolves InviteResolvable to an invite code.
* @param {InviteResolvable} data The invite resolvable to resolve
* @returns {string}
*/
resolveInviteCode(data) {
const inviteRegex = /discord(?:app\.com\/invite|\.gg)\/([\w-]{2,255})/i;
const match = inviteRegex.exec(data);
if (match && match[1]) return match[1];
return data;
}
/**
* Data that can be resolved to give a string. This can be:
* * A string
* * An array (joined with a new line delimiter to give a string)
* * Any value
* @typedef {string|Array|*} StringResolvable
*/
/**
* Resolves a StringResolvable to a string.
* @param {StringResolvable} data The string resolvable to resolve
* @returns {string}
*/
resolveString(data) {
if (typeof data === 'string') return data;
if (data instanceof Array) return data.join('\n');
return String(data);
}
/**
* Resolves a Base64Resolvable, a string, or a BufferResolvable to a Base 64 image.
* @param {BufferResolvable|Base64Resolvable} image The image to be resolved
* @returns {Promise<?string>}
*/
resolveImage(image) {
if (!image) return Promise.resolve(null);
if (typeof image === 'string' && image.startsWith('data:')) {
return Promise.resolve(image);
}
return this.resolveFile(image).then(this.resolveBase64);
}
/**
* Data that resolves to give a Base64 string, typically for image uploading. This can be:
* * A Buffer
* * A base64 string
* @typedef {Buffer|string} Base64Resolvable
*/
/**
* Resolves a Base64Resolvable to a Base 64 image.
* @param {Base64Resolvable} data The base 64 resolvable you want to resolve
* @returns {?string}
*/
resolveBase64(data) {
if (data instanceof Buffer) return `data:image/jpg;base64,${data.toString('base64')}`;
return data;
}
/**
* Data that can be resolved to give a Buffer. This can be:
* * A Buffer
* * The path to a local file
* * A URL
* * A Stream
* @typedef {string|Buffer} BufferResolvable
*/
/**
* @external Stream
* @see {@link https://nodejs.org/api/stream.html}
*/
/**
* Resolves a BufferResolvable to a Buffer.
* @param {BufferResolvable|Stream} resource The buffer or stream resolvable to resolve
* @returns {Promise<Buffer>}
*/
resolveFile(resource) {
if (resource instanceof Buffer) return Promise.resolve(resource);
if (this.client.browser && resource instanceof ArrayBuffer) return Promise.resolve(convertToBuffer(resource));
if (typeof resource === 'string') {
return new Promise((resolve, reject) => {
if (/^https?:\/\//.test(resource)) {
snekfetch.get(resource)
.end((err, res) => {
if (err) return reject(err);
if (!(res.body instanceof Buffer)) return reject(new TypeError('The response body isn\'t a Buffer.'));
return resolve(res.body);
});
} else {
const file = path.resolve(resource);
fs.stat(file, (err, stats) => {
if (err) return reject(err);
if (!stats || !stats.isFile()) return reject(new Error(`The file could not be found: ${file}`));
fs.readFile(file, (err2, data) => {
if (err2) reject(err2); else resolve(data);
});
return null;
});
}
});
} else if (resource.pipe && typeof resource.pipe === 'function') {
return new Promise((resolve, reject) => {
const buffers = [];
resource.once('error', reject);
resource.on('data', data => buffers.push(data));
resource.once('end', () => resolve(Buffer.concat(buffers)));
});
}
return Promise.reject(new TypeError('The resource must be a string or Buffer.'));
}
/**
* Data that can be resolved to give an emoji identifier. This can be:
* * The unicode representation of an emoji
* * A custom emoji ID
* * An Emoji object
* * A ReactionEmoji object
* @typedef {string|Emoji|ReactionEmoji} EmojiIdentifierResolvable
*/
/**
* Resolves an EmojiResolvable to an emoji identifier.
* @param {EmojiIdentifierResolvable} emoji The emoji resolvable to resolve
* @returns {?string}
*/
resolveEmojiIdentifier(emoji) {
if (emoji instanceof Emoji || emoji instanceof ReactionEmoji) return emoji.identifier;
if (typeof emoji === 'string') {
if (this.client.emojis.has(emoji)) return this.client.emojis.get(emoji).identifier;
else if (!emoji.includes('%')) return encodeURIComponent(emoji);
else return emoji;
}
return null;
}
/**
* Can be a Hex Literal, Hex String, Number, RGB Array, or one of the following
* ```
* [
* 'DEFAULT',
* 'AQUA',
* 'GREEN',
* 'BLUE',
* 'PURPLE',
* 'GOLD',
* 'ORANGE',
* 'RED',
* 'GREY',
* 'DARKER_GREY',
* 'NAVY',
* 'DARK_AQUA',
* 'DARK_GREEN',
* 'DARK_BLUE',
* 'DARK_PURPLE',
* 'DARK_GOLD',
* 'DARK_ORANGE',
* 'DARK_RED',
* 'DARK_GREY',
* 'LIGHT_GREY',
* 'DARK_NAVY',
* 'RANDOM',
* ]
* ```
* or something like
* ```
* [255, 0, 255]
* ```
* for purple
* @typedef {string|number|Array} ColorResolvable
*/
/**
* Resolves a ColorResolvable into a color number.
* @param {ColorResolvable} color Color to resolve
* @returns {number} A color
*/
static resolveColor(color) {
if (typeof color === 'string') {
if (color === 'RANDOM') return Math.floor(Math.random() * (0xFFFFFF + 1));
if (color === 'DEFAULT') return 0;
color = Constants.Colors[color] || parseInt(color.replace('#', ''), 16);
} else if (color instanceof Array) {
color = (color[0] << 16) + (color[1] << 8) + color[2];
}
if (color < 0 || color > 0xFFFFFF) {
throw new RangeError('Color must be within the range 0 - 16777215 (0xFFFFFF).');
} else if (color && isNaN(color)) {
throw new TypeError('Unable to convert color to a number.');
}
return color;
}
/**
* @param {ColorResolvable} color Color to resolve
* @returns {number} A color
*/
resolveColor(color) {
return this.constructor.resolveColor(color);
}
}
module.exports = ClientDataResolver;

View File

@@ -1,73 +0,0 @@
const Constants = require('../util/Constants');
const WebSocketConnection = require('./websocket/WebSocketConnection');
/**
* Manages the state and background tasks of the client.
* @private
*/
class ClientManager {
constructor(client) {
/**
* The client that instantiated this Manager
* @type {Client}
*/
this.client = client;
/**
* The heartbeat interval
* @type {?number}
*/
this.heartbeatInterval = null;
}
/**
* The status of the client
* @type {number}
*/
get status() {
return this.connection ? this.connection.status : Constants.Status.IDLE;
}
/**
* Connects the client to the WebSocket.
* @param {string} token The authorization token
* @param {Function} resolve Function to run when connection is successful
* @param {Function} reject Function to run when connection fails
*/
connectToWebSocket(token, resolve, reject) {
this.client.emit(Constants.Events.DEBUG, `Authenticated using token ${token}`);
this.client.token = token;
const timeout = this.client.setTimeout(() => reject(new Error(Constants.Errors.TOOK_TOO_LONG)), 1000 * 300);
this.client.rest.methods.getGateway().then(res => {
const protocolVersion = Constants.DefaultOptions.ws.version;
const gateway = `${res.url}/?v=${protocolVersion}&encoding=${WebSocketConnection.ENCODING}`;
this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`);
this.client.ws.connect(gateway);
this.client.ws.connection.once('close', event => {
if (event.code === 4004) reject(new Error(Constants.Errors.BAD_LOGIN));
if (event.code === 4010) reject(new Error(Constants.Errors.INVALID_SHARD));
if (event.code === 4011) reject(new Error(Constants.Errors.SHARDING_REQUIRED));
});
this.client.once(Constants.Events.READY, () => {
resolve(token);
this.client.clearTimeout(timeout);
});
}, reject);
}
destroy() {
this.client.ws.destroy();
this.client.rest.destroy();
if (!this.client.user) return Promise.resolve();
if (this.client.user.bot) {
this.client.token = null;
return Promise.resolve();
} else {
return this.client.rest.methods.logout().then(() => {
this.client.token = null;
});
}
}
}
module.exports = ClientManager;

View File

@@ -1,14 +1,14 @@
'use strict';
const BaseClient = require('./BaseClient');
const Webhook = require('../structures/Webhook');
const RESTManager = require('./rest/RESTManager');
const ClientDataResolver = require('./ClientDataResolver');
const Constants = require('../util/Constants');
const Util = require('../util/Util');
/**
* The webhook client.
* @extends {Webhook}
* @implements {Webhook}
* @extends {BaseClient}
*/
class WebhookClient extends Webhook {
class WebhookClient extends BaseClient {
/**
* @param {Snowflake} id ID of the webhook
* @param {string} token Token of the webhook
@@ -16,103 +16,16 @@ class WebhookClient extends Webhook {
* @example
* // Create a new webhook and send a message
* const hook = new Discord.WebhookClient('1234', 'abcdef');
* hook.sendMessage('This will send a message').catch(console.error);
* hook.send('This will send a message').catch(console.error);
*/
constructor(id, token, options) {
super(null, id, token);
/**
* The options the client was instantiated with
* @type {ClientOptions}
*/
this.options = Util.mergeDefault(Constants.DefaultOptions, options);
/**
* The REST manager of the client
* @type {RESTManager}
* @private
*/
this.rest = new RESTManager(this);
/**
* The data resolver of the client
* @type {ClientDataResolver}
* @private
*/
this.resolver = new ClientDataResolver(this);
/**
* Timeouts set by {@link WebhookClient#setTimeout} that are still active
* @type {Set<Timeout>}
* @private
*/
this._timeouts = new Set();
/**
* Intervals set by {@link WebhookClient#setInterval} that are still active
* @type {Set<Timeout>}
* @private
*/
this._intervals = new Set();
}
/**
* Sets a timeout that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setTimeout(fn, delay, ...args) {
const timeout = setTimeout(() => {
fn(...args);
this._timeouts.delete(timeout);
}, delay);
this._timeouts.add(timeout);
return timeout;
}
/**
* Clears a timeout.
* @param {Timeout} timeout Timeout to cancel
*/
clearTimeout(timeout) {
clearTimeout(timeout);
this._timeouts.delete(timeout);
}
/**
* Sets an interval that will be automatically cancelled if the client is destroyed.
* @param {Function} fn Function to execute
* @param {number} delay Time to wait before executing (in milliseconds)
* @param {...*} args Arguments for the function
* @returns {Timeout}
*/
setInterval(fn, delay, ...args) {
const interval = setInterval(fn, delay, ...args);
this._intervals.add(interval);
return interval;
}
/**
* Clears an interval.
* @param {Timeout} interval Interval to cancel
*/
clearInterval(interval) {
clearInterval(interval);
this._intervals.delete(interval);
}
/**
* Destroys the client.
*/
destroy() {
for (const t of this._timeouts) clearTimeout(t);
for (const i of this._intervals) clearInterval(i);
this._timeouts.clear();
this._intervals.clear();
super(options);
Object.defineProperty(this, 'client', { value: this });
this.id = id;
Object.defineProperty(this, 'token', { value: token, writable: true, configurable: true });
}
}
Webhook.applyToClass(WebhookClient);
module.exports = WebhookClient;

View File

@@ -1,3 +1,7 @@
'use strict';
const { PartialTypes } = require('../../util/Constants');
/*
ABOUT ACTIONS
@@ -18,6 +22,84 @@ class GenericAction {
handle(data) {
return data;
}
getPayload(data, manager, id, partialType, cache) {
const existing = manager.cache.get(id);
if (!existing && this.client.options.partials.includes(partialType)) {
return manager.add(data, cache);
}
return existing;
}
getChannel(data) {
const id = data.channel_id || data.id;
return (
data.channel ||
this.getPayload(
{
id,
guild_id: data.guild_id,
recipients: [data.author || { id: data.user_id }],
},
this.client.channels,
id,
PartialTypes.CHANNEL,
)
);
}
getMessage(data, channel, cache) {
const id = data.message_id || data.id;
return (
data.message ||
this.getPayload(
{
id,
channel_id: channel.id,
guild_id: data.guild_id || (channel.guild ? channel.guild.id : null),
},
channel.messages,
id,
PartialTypes.MESSAGE,
cache,
)
);
}
getReaction(data, message, user) {
const id = data.emoji.id || decodeURIComponent(data.emoji.name);
return this.getPayload(
{
emoji: data.emoji,
count: message.partial ? null : 0,
me: user ? user.id === this.client.user.id : false,
},
message.reactions,
id,
PartialTypes.REACTION,
);
}
getMember(data, guild) {
return this.getPayload(data, guild.members, data.user.id, PartialTypes.GUILD_MEMBER);
}
getUser(data) {
const id = data.user_id;
return data.user || this.getPayload({ id }, this.client.users, id, PartialTypes.USER);
}
getUserFromMember(data) {
if (data.guild_id && data.member && data.member.user) {
const guild = this.client.guilds.cache.get(data.guild_id);
if (guild) {
return guild.members.add(data.member).user;
} else {
return this.client.users.add(data.member.user);
}
}
return this.getUser(data);
}
}
module.exports = GenericAction;

View File

@@ -1,3 +1,5 @@
'use strict';
class ActionsManager {
constructor(client) {
this.client = client;
@@ -9,27 +11,32 @@ class ActionsManager {
this.register(require('./MessageReactionAdd'));
this.register(require('./MessageReactionRemove'));
this.register(require('./MessageReactionRemoveAll'));
this.register(require('./MessageReactionRemoveEmoji'));
this.register(require('./ChannelCreate'));
this.register(require('./ChannelDelete'));
this.register(require('./ChannelUpdate'));
this.register(require('./GuildDelete'));
this.register(require('./GuildUpdate'));
this.register(require('./GuildMemberGet'));
this.register(require('./InviteCreate'));
this.register(require('./InviteDelete'));
this.register(require('./GuildMemberRemove'));
this.register(require('./GuildMemberUpdate'));
this.register(require('./GuildBanRemove'));
this.register(require('./GuildRoleCreate'));
this.register(require('./GuildRoleDelete'));
this.register(require('./GuildRoleUpdate'));
this.register(require('./UserGet'));
this.register(require('./PresenceUpdate'));
this.register(require('./UserUpdate'));
this.register(require('./UserNoteUpdate'));
this.register(require('./GuildSync'));
this.register(require('./VoiceStateUpdate'));
this.register(require('./GuildEmojiCreate'));
this.register(require('./GuildEmojiDelete'));
this.register(require('./GuildEmojiUpdate'));
this.register(require('./GuildEmojisUpdate'));
this.register(require('./GuildRolesPositionUpdate'));
this.register(require('./GuildChannelsPositionUpdate'));
this.register(require('./GuildIntegrationsUpdate'));
this.register(require('./WebhooksUpdate'));
this.register(require('./TypingStart'));
}
register(Action) {

View File

@@ -1,9 +1,21 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class ChannelCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.dataManager.newChannel(data);
const existing = client.channels.cache.has(data.id);
const channel = client.channels.add(data);
if (!existing && channel) {
/**
* Emitted whenever a channel is created.
* @event Client#channelCreate
* @param {DMChannel|GuildChannel} channel The channel that was created
*/
client.emit(Events.CHANNEL_CREATE, channel);
}
return { channel };
}
}

View File

@@ -1,4 +1,8 @@
'use strict';
const Action = require('./Action');
const DMChannel = require('../../structures/DMChannel');
const { Events } = require('../../util/Constants');
class ChannelDeleteAction extends Action {
constructor(client) {
@@ -8,22 +12,26 @@ class ChannelDeleteAction extends Action {
handle(data) {
const client = this.client;
let channel = client.channels.cache.get(data.id);
let channel = client.channels.get(data.id);
if (channel) {
client.dataManager.killChannel(channel);
this.deleted.set(channel.id, channel);
this.scheduleForDeletion(channel.id);
} else {
channel = this.deleted.get(data.id) || null;
client.channels.remove(channel.id);
channel.deleted = true;
if (channel.messages && !(channel instanceof DMChannel)) {
for (const message of channel.messages.cache.values()) {
message.deleted = true;
}
}
/**
* Emitted whenever a channel is deleted.
* @event Client#channelDelete
* @param {DMChannel|GuildChannel} channel The channel that was deleted
*/
client.emit(Events.CHANNEL_DELETE, channel);
}
return { channel };
}
scheduleForDeletion(id) {
this.client.setTimeout(() => this.deleted.delete(id), this.client.options.restWsBridgeTimeout);
}
}
module.exports = ChannelDeleteAction;

View File

@@ -1,34 +1,33 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const Util = require('../../util/Util');
const Channel = require('../../structures/Channel');
const { ChannelTypes } = require('../../util/Constants');
class ChannelUpdateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get(data.id);
let channel = client.channels.cache.get(data.id);
if (channel) {
const oldChannel = Util.cloneObject(channel);
channel.setup(data);
client.emit(Constants.Events.CHANNEL_UPDATE, oldChannel, channel);
const old = channel._update(data);
if (ChannelTypes[channel.type.toUpperCase()] !== data.type) {
const newChannel = Channel.create(this.client, data, channel.guild);
for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message);
newChannel._typing = new Map(channel._typing);
channel = newChannel;
this.client.channels.cache.set(channel.id, channel);
}
return {
old: oldChannel,
old,
updated: channel,
};
}
return {
old: null,
updated: null,
};
return {};
}
}
/**
* Emitted whenever a channel is updated - e.g. name change, topic change.
* @event Client#channelUpdate
* @param {Channel} oldChannel The channel before the update
* @param {Channel} newChannel The channel after the update
*/
module.exports = ChannelUpdateAction;

View File

@@ -1,12 +1,20 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
class GuildBanRemove extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const user = client.dataManager.newUser(data.user);
if (guild && user) client.emit(Constants.Events.GUILD_BAN_REMOVE, guild, user);
const guild = client.guilds.cache.get(data.guild_id);
const user = client.users.add(data.user);
/**
* Emitted whenever a member is unbanned from a guild.
* @event Client#guildBanRemove
* @param {Guild} guild The guild that the unban occurred in
* @param {User} user The user that was unbanned
*/
if (guild && user) client.emit(Events.GUILD_BAN_REMOVE, guild, user);
}
}

View File

@@ -1,14 +1,16 @@
'use strict';
const Action = require('./Action');
class GuildChannelsPositionUpdate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
if (guild) {
for (const partialChannel of data.channels) {
const channel = guild.channels.get(partialChannel.id);
if (channel) channel.position = partialChannel.position;
const channel = guild.channels.cache.get(partialChannel.id);
if (channel) channel.rawPosition = partialChannel.position;
}
}

View File

@@ -1,5 +1,7 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
class GuildDeleteAction extends Action {
constructor(client) {
@@ -10,16 +12,22 @@ class GuildDeleteAction extends Action {
handle(data) {
const client = this.client;
let guild = client.guilds.get(data.id);
let guild = client.guilds.cache.get(data.id);
if (guild) {
for (const channel of guild.channels.values()) {
for (const channel of guild.channels.cache.values()) {
if (channel.type === 'text') channel.stopTyping(true);
}
if (guild.available && data.unavailable) {
if (data.unavailable) {
// Guild is unavailable
guild.available = false;
client.emit(Constants.Events.GUILD_UNAVAILABLE, guild);
/**
* Emitted whenever a guild becomes unavailable, likely due to a server outage.
* @event Client#guildUnavailable
* @param {Guild} guild The guild that has become unavailable
*/
client.emit(Events.GUILD_UNAVAILABLE, guild);
// Stops the GuildDelete packet thinking a guild was actually deleted,
// handles emitting of event itself
@@ -28,11 +36,20 @@ class GuildDeleteAction extends Action {
};
}
for (const channel of guild.channels.values()) this.client.channels.delete(channel.id);
if (guild.voiceConnection) guild.voiceConnection.disconnect();
for (const channel of guild.channels.cache.values()) this.client.channels.remove(channel.id);
if (guild.voice && guild.voice.connection) guild.voice.connection.disconnect();
// Delete guild
client.guilds.delete(guild.id);
client.guilds.cache.delete(guild.id);
guild.deleted = true;
/**
* Emitted whenever a guild kicks the client or the guild is deleted/left.
* @event Client#guildDelete
* @param {Guild} guild The guild that was deleted
*/
client.emit(Events.GUILD_DELETE, guild);
this.deleted.set(guild.id, guild);
this.scheduleForDeletion(guild.id);
} else {
@@ -47,10 +64,4 @@ class GuildDeleteAction extends Action {
}
}
/**
* Emitted whenever a guild becomes unavailable, likely due to a server outage.
* @event Client#guildUnavailable
* @param {Guild} guild The guild that has become unavailable
*/
module.exports = GuildDeleteAction;

View File

@@ -1,17 +1,20 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class GuildEmojiCreateAction extends Action {
handle(guild, createdEmoji) {
const client = this.client;
const emoji = client.dataManager.newEmoji(createdEmoji, guild);
const already = guild.emojis.cache.has(createdEmoji.id);
const emoji = guild.emojis.add(createdEmoji);
/**
* Emitted whenever a custom emoji is created in a guild.
* @event Client#emojiCreate
* @param {GuildEmoji} emoji The emoji that was created
*/
if (!already) this.client.emit(Events.GUILD_EMOJI_CREATE, emoji);
return { emoji };
}
}
/**
* Emitted whenever a custom emoji is created in a guild.
* @event Client#emojiCreate
* @param {Emoji} emoji The emoji that was created
*/
module.exports = GuildEmojiCreateAction;

View File

@@ -1,17 +1,20 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class GuildEmojiDeleteAction extends Action {
handle(emoji) {
const client = this.client;
client.dataManager.killEmoji(emoji);
emoji.guild.emojis.cache.delete(emoji.id);
emoji.deleted = true;
/**
* Emitted whenever a custom emoji is deleted in a guild.
* @event Client#emojiDelete
* @param {GuildEmoji} emoji The emoji that was deleted
*/
this.client.emit(Events.GUILD_EMOJI_DELETE, emoji);
return { emoji };
}
}
/**
* Emitted whenever a custom guild emoji is deleted.
* @event Client#emojiDelete
* @param {Emoji} emoji The emoji that was deleted
*/
module.exports = GuildEmojiDeleteAction;

View File

@@ -1,17 +1,20 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class GuildEmojiUpdateAction extends Action {
handle(oldEmoji, newEmoji) {
const emoji = this.client.dataManager.updateEmoji(oldEmoji, newEmoji);
return { emoji };
handle(current, data) {
const old = current._update(data);
/**
* Emitted whenever a custom emoji is updated in a guild.
* @event Client#emojiUpdate
* @param {GuildEmoji} oldEmoji The old emoji
* @param {GuildEmoji} newEmoji The new emoji
*/
this.client.emit(Events.GUILD_EMOJI_UPDATE, old, current);
return { emoji: current };
}
}
/**
* Emitted whenever a custom guild emoji is updated.
* @event Client#emojiUpdate
* @param {Emoji} oldEmoji The old emoji
* @param {Emoji} newEmoji The new emoji
*/
module.exports = GuildEmojiUpdateAction;

View File

@@ -1,24 +1,20 @@
const Action = require('./Action');
'use strict';
function mappify(iterable) {
const map = new Map();
for (const x of iterable) map.set(...x);
return map;
}
const Action = require('./Action');
class GuildEmojisUpdateAction extends Action {
handle(data) {
const guild = this.client.guilds.get(data.guild_id);
const guild = this.client.guilds.cache.get(data.guild_id);
if (!guild || !guild.emojis) return;
const deletions = mappify(guild.emojis.entries());
const deletions = new Map(guild.emojis.cache);
for (const emoji of data.emojis) {
// Determine type of emoji event
const cachedEmoji = guild.emojis.get(emoji.id);
const cachedEmoji = guild.emojis.cache.get(emoji.id);
if (cachedEmoji) {
deletions.delete(emoji.id);
if (!cachedEmoji.equals(emoji, true)) {
if (!cachedEmoji.equals(emoji)) {
// Emoji updated
this.client.actions.GuildEmojiUpdate.handle(cachedEmoji, emoji);
}

View File

@@ -0,0 +1,19 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class GuildIntegrationsUpdate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.cache.get(data.guild_id);
/**
* Emitted whenever a guild integration is updated
* @event Client#guildIntegrationsUpdate
* @param {Guild} guild The guild whose integrations were updated
*/
if (guild) client.emit(Events.GUILD_INTEGRATIONS_UPDATE, guild);
}
}
module.exports = GuildIntegrationsUpdate;

View File

@@ -1,10 +0,0 @@
const Action = require('./Action');
class GuildMemberGetAction extends Action {
handle(guild, data) {
const member = guild._addMember(data, false);
return { member };
}
}
module.exports = GuildMemberGetAction;

View File

@@ -1,40 +1,30 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events, Status } = require('../../util/Constants');
class GuildMemberRemoveAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
handle(data, shard) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
let member = null;
if (guild) {
member = guild.members.get(data.user.id);
member = this.getMember({ user: data.user }, guild);
guild.memberCount--;
if (member) {
guild.memberCount--;
guild._removeMember(member);
this.deleted.set(guild.id + data.user.id, member);
if (client.status === Constants.Status.READY) client.emit(Constants.Events.GUILD_MEMBER_REMOVE, member);
this.scheduleForDeletion(guild.id, data.user.id);
} else {
member = this.deleted.get(guild.id + data.user.id) || null;
member.deleted = true;
guild.members.cache.delete(member.id);
/**
* Emitted whenever a member leaves a guild, or is kicked.
* @event Client#guildMemberRemove
* @param {GuildMember} member The member that has left/been kicked from the guild
*/
if (shard.status === Status.READY) client.emit(Events.GUILD_MEMBER_REMOVE, member);
}
guild.voiceStates.cache.delete(data.user.id);
}
return { guild, member };
}
scheduleForDeletion(guildID, userID) {
this.client.setTimeout(() => this.deleted.delete(guildID + userID), this.client.options.restWsBridgeTimeout);
}
}
/**
* Emitted whenever a member leaves a guild, or is kicked.
* @event Client#guildMemberRemove
* @param {GuildMember} member The member that has left/been kicked from the guild
*/
module.exports = GuildMemberRemoveAction;

View File

@@ -0,0 +1,44 @@
'use strict';
const Action = require('./Action');
const { Status, Events } = require('../../util/Constants');
class GuildMemberUpdateAction extends Action {
handle(data, shard) {
const { client } = this;
if (data.user.username) {
const user = client.users.cache.get(data.user.id);
if (!user) {
client.users.add(data.user);
} else if (!user.equals(data.user)) {
client.actions.UserUpdate.handle(data.user);
}
}
const guild = client.guilds.cache.get(data.guild_id);
if (guild) {
const member = this.getMember({ user: data.user }, guild);
if (member) {
const old = member._update(data);
/**
* Emitted whenever a guild member changes - i.e. new role, removed role, nickname.
* Also emitted when the user's details (e.g. username) change.
* @event Client#guildMemberUpdate
* @param {GuildMember} oldMember The member before the update
* @param {GuildMember} newMember The member after the update
*/
if (shard.status === Status.READY) client.emit(Events.GUILD_MEMBER_UPDATE, old, member);
} else {
const newMember = guild.members.add(data);
/**
* Emitted whenever a member becomes available in a large guild.
* @event Client#guildMemberAvailable
* @param {GuildMember} member The member that became available
*/
this.client.emit(Events.GUILD_MEMBER_AVAILABLE, newMember);
}
}
}
}
module.exports = GuildMemberUpdateAction;

View File

@@ -1,26 +1,25 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const Role = require('../../structures/Role');
const { Events } = require('../../util/Constants');
class GuildRoleCreate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
let role;
if (guild) {
const already = guild.roles.has(data.role.id);
role = new Role(guild, data.role);
guild.roles.set(role.id, role);
if (!already) client.emit(Constants.Events.GUILD_ROLE_CREATE, role);
const already = guild.roles.cache.has(data.role.id);
role = guild.roles.add(data.role);
/**
* Emitted whenever a role is created.
* @event Client#roleCreate
* @param {Role} role The role that was created
*/
if (!already) client.emit(Events.GUILD_ROLE_CREATE, role);
}
return { role };
}
}
/**
* Emitted whenever a role is created.
* @event Client#roleCreate
* @param {Role} role The role that was created
*/
module.exports = GuildRoleCreate;

View File

@@ -1,41 +1,30 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
class GuildRoleDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
let role;
if (guild) {
role = guild.roles.get(data.role_id);
role = guild.roles.cache.get(data.role_id);
if (role) {
guild.roles.delete(data.role_id);
this.deleted.set(guild.id + data.role_id, role);
this.scheduleForDeletion(guild.id, data.role_id);
client.emit(Constants.Events.GUILD_ROLE_DELETE, role);
} else {
role = this.deleted.get(guild.id + data.role_id) || null;
guild.roles.cache.delete(data.role_id);
role.deleted = true;
/**
* Emitted whenever a guild role is deleted.
* @event Client#roleDelete
* @param {Role} role The role that was deleted
*/
client.emit(Events.GUILD_ROLE_DELETE, role);
}
}
return { role };
}
scheduleForDeletion(guildID, roleID) {
this.client.setTimeout(() => this.deleted.delete(guildID + roleID), this.client.options.restWsBridgeTimeout);
}
}
/**
* Emitted whenever a guild role is deleted.
* @event Client#roleDelete
* @param {Role} role The role that was deleted
*/
module.exports = GuildRoleDeleteAction;

View File

@@ -1,25 +1,30 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const Util = require('../../util/Util');
const { Events } = require('../../util/Constants');
class GuildRoleUpdateAction extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
if (guild) {
const roleData = data.role;
let oldRole = null;
let old = null;
const role = guild.roles.get(roleData.id);
const role = guild.roles.cache.get(data.role.id);
if (role) {
oldRole = Util.cloneObject(role);
role.setup(data.role);
client.emit(Constants.Events.GUILD_ROLE_UPDATE, oldRole, role);
old = role._update(data.role);
/**
* Emitted whenever a guild role is updated.
* @event Client#roleUpdate
* @param {Role} oldRole The role before the update
* @param {Role} newRole The role after the update
*/
client.emit(Events.GUILD_ROLE_UPDATE, old, role);
}
return {
old: oldRole,
old,
updated: role,
};
}
@@ -31,11 +36,4 @@ class GuildRoleUpdateAction extends Action {
}
}
/**
* Emitted whenever a guild role is updated.
* @event Client#roleUpdate
* @param {Role} oldRole The role before the update
* @param {Role} newRole The role after the update
*/
module.exports = GuildRoleUpdateAction;

View File

@@ -1,14 +1,16 @@
'use strict';
const Action = require('./Action');
class GuildRolesPositionUpdate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.guild_id);
const guild = client.guilds.cache.get(data.guild_id);
if (guild) {
for (const partialRole of data.roles) {
const role = guild.roles.get(partialRole.id);
if (role) role.position = partialRole.position;
const role = guild.roles.cache.get(partialRole.id);
if (role) role.rawPosition = partialRole.position;
}
}

View File

@@ -1,29 +0,0 @@
const Action = require('./Action');
class GuildSync extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.id);
if (guild) {
if (data.presences) {
for (const presence of data.presences) guild._setPresence(presence.user.id, presence);
}
if (data.members) {
for (const syncMember of data.members) {
const member = guild.members.get(syncMember.user.id);
if (member) {
guild._updateMember(member, syncMember);
} else {
guild._addMember(syncMember, false);
}
}
}
if ('large' in data) guild.large = data.large;
}
}
}
module.exports = GuildSync;

View File

@@ -1,18 +1,24 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const Util = require('../../util/Util');
const { Events } = require('../../util/Constants');
class GuildUpdateAction extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.get(data.id);
const guild = client.guilds.cache.get(data.id);
if (guild) {
const oldGuild = Util.cloneObject(guild);
guild.setup(data);
client.emit(Constants.Events.GUILD_UPDATE, oldGuild, guild);
const old = guild._update(data);
/**
* Emitted whenever a guild is updated - e.g. name change.
* @event Client#guildUpdate
* @param {Guild} oldGuild The guild before the update
* @param {Guild} newGuild The guild after the update
*/
client.emit(Events.GUILD_UPDATE, old, guild);
return {
old: oldGuild,
old,
updated: guild,
};
}
@@ -24,11 +30,4 @@ class GuildUpdateAction extends Action {
}
}
/**
* Emitted whenever a guild is updated - e.g. name change.
* @event Client#guildUpdate
* @param {Guild} oldGuild The guild before the update
* @param {Guild} newGuild The guild after the update
*/
module.exports = GuildUpdateAction;

View File

@@ -0,0 +1,28 @@
'use strict';
const Action = require('./Action');
const Invite = require('../../structures/Invite');
const { Events } = require('../../util/Constants');
class InviteCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.cache.get(data.channel_id);
const guild = client.guilds.cache.get(data.guild_id);
if (!channel) return false;
const inviteData = Object.assign(data, { channel, guild });
const invite = new Invite(client, inviteData);
/**
* Emitted when an invite is created.
* <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild,
* or `MANAGE_CHANNEL` permissions for the channel.</info>
* @event Client#inviteCreate
* @param {Invite} invite The invite that was created
*/
client.emit(Events.INVITE_CREATE, invite);
return { invite };
}
}
module.exports = InviteCreateAction;

View File

@@ -0,0 +1,29 @@
'use strict';
const Action = require('./Action');
const Invite = require('../../structures/Invite');
const { Events } = require('../../util/Constants');
class InviteDeleteAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.cache.get(data.channel_id);
const guild = client.guilds.cache.get(data.guild_id);
if (!channel && !guild) return false;
const inviteData = Object.assign(data, { channel, guild });
const invite = new Invite(client, inviteData);
/**
* Emitted when an invite is deleted.
* <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild,
* or `MANAGE_CHANNEL` permissions for the channel.</info>
* @event Client#inviteDelete
* @param {Invite} invite The invite that was deleted
*/
client.emit(Events.INVITE_DELETE, invite);
return { invite };
}
}
module.exports = InviteDeleteAction;

View File

@@ -1,54 +1,38 @@
'use strict';
const Action = require('./Action');
const Message = require('../../structures/Message');
const { Events } = require('../../util/Constants');
class MessageCreateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get((data instanceof Array ? data[0] : data).channel_id);
const user = client.users.get((data instanceof Array ? data[0] : data).author.id);
const channel = client.channels.cache.get(data.channel_id);
if (channel) {
const member = channel.guild ? channel.guild.member(user) : null;
if (data instanceof Array) {
const messages = new Array(data.length);
for (let i = 0; i < data.length; i++) {
messages[i] = channel._cacheMessage(new Message(channel, data[i], client));
}
const lastMessage = messages[messages.length - 1];
channel.lastMessageID = lastMessage.id;
channel.lastMessage = lastMessage;
if (user) {
user.lastMessageID = lastMessage.id;
user.lastMessage = lastMessage;
}
if (member) {
member.lastMessageID = lastMessage.id;
member.lastMessage = lastMessage;
}
return {
messages,
};
} else {
const message = channel._cacheMessage(new Message(channel, data, client));
channel.lastMessageID = data.id;
channel.lastMessage = message;
if (user) {
user.lastMessageID = data.id;
user.lastMessage = message;
}
if (member) {
member.lastMessageID = data.id;
member.lastMessage = message;
}
return {
message,
};
const existing = channel.messages.cache.get(data.id);
if (existing) return { message: existing };
const message = channel.messages.add(data);
const user = message.author;
let member = message.member;
channel.lastMessageID = data.id;
if (user) {
user.lastMessageID = data.id;
user.lastMessageChannelID = channel.id;
}
if (member) {
member.lastMessageID = data.id;
member.lastMessageChannelID = channel.id;
}
/**
* Emitted whenever a message is created.
* @event Client#message
* @param {Message} message The created message
*/
client.emit(Events.MESSAGE_CREATE, message);
return { message };
}
return {
message: null,
};
return {};
}
}

View File

@@ -1,34 +1,29 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class MessageDeleteAction extends Action {
constructor(client) {
super(client);
this.deleted = new Map();
}
handle(data) {
const client = this.client;
const channel = client.channels.get(data.channel_id);
const channel = this.getChannel(data);
let message;
if (channel) {
message = channel.messages.get(data.id);
message = this.getMessage(data, channel);
if (message) {
channel.messages.delete(message.id);
this.deleted.set(channel.id + message.id, message);
this.scheduleForDeletion(channel.id, message.id);
} else {
message = this.deleted.get(channel.id + data.id) || null;
channel.messages.cache.delete(message.id);
message.deleted = true;
/**
* Emitted whenever a message is deleted.
* @event Client#messageDelete
* @param {Message} message The deleted message
*/
client.emit(Events.MESSAGE_DELETE, message);
}
}
return { message };
}
scheduleForDeletion(channelID, messageID) {
this.client.setTimeout(() => this.deleted.delete(channelID + messageID),
this.client.options.restWsBridgeTimeout);
}
}
module.exports = MessageDeleteAction;

View File

@@ -1,25 +1,42 @@
'use strict';
const Action = require('./Action');
const Collection = require('../../util/Collection');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
class MessageDeleteBulkAction extends Action {
handle(data) {
const messages = new Collection();
const client = this.client;
const channel = client.channels.cache.get(data.channel_id);
if (!data.messages) {
const channel = this.client.channels.get(data.channel_id);
for (const id of data.ids) {
const message = channel.messages.get(id);
if (message) messages.set(message.id, message);
}
} else {
for (const msg of data.messages) {
messages.set(msg.id, msg);
if (channel) {
const ids = data.ids;
const messages = new Collection();
for (const id of ids) {
const message = this.getMessage(
{
id,
guild_id: data.guild_id,
},
channel,
false,
);
if (message) {
message.deleted = true;
messages.set(message.id, message);
channel.messages.cache.delete(id);
}
}
/**
* Emitted whenever messages are deleted in bulk.
* @event Client#messageDeleteBulk
* @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their ID
*/
if (messages.size > 0) client.emit(Events.MESSAGE_BULK_DELETE, messages);
return { messages };
}
if (messages.size > 0) this.client.emit(Constants.Events.MESSAGE_BULK_DELETE, messages);
return { messages };
return {};
}
}

View File

@@ -1,37 +1,55 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
const { PartialTypes } = require('../../util/Constants');
/*
{ user_id: 'id',
message_id: 'id',
emoji: { name: '<27>', id: null },
channel_id: 'id' } }
channel_id: 'id',
// If originating from a guild
guild_id: 'id',
member: { ..., user: { ... } } }
*/
class MessageReactionAdd extends Action {
handle(data) {
const user = this.client.users.get(data.user_id);
if (!user) return false;
// Verify channel
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
// Verify message
const message = channel.messages.get(data.message_id);
if (!message) return false;
if (!data.emoji) return false;
const user = this.getUserFromMember(data);
if (!user) return false;
// Verify channel
const channel = this.getChannel(data);
if (!channel || channel.type === 'voice') return false;
// Verify message
const message = this.getMessage(data, channel);
if (!message) return false;
// Verify reaction
const reaction = message._addReaction(data.emoji, user);
if (reaction) this.client.emit(Constants.Events.MESSAGE_REACTION_ADD, reaction, user);
if (message.partial && !this.client.options.partials.includes(PartialTypes.REACTION)) return false;
const existing = message.reactions.cache.get(data.emoji.id || data.emoji.name);
if (existing && existing.users.cache.has(user.id)) return { message, reaction: existing, user };
const reaction = message.reactions.add({
emoji: data.emoji,
count: message.partial ? null : 0,
me: user.id === this.client.user.id,
});
if (!reaction) return false;
reaction._add(user);
/**
* Emitted whenever a reaction is added to a cached message.
* @event Client#messageReactionAdd
* @param {MessageReaction} messageReaction The reaction object
* @param {User} user The user that applied the guild or reaction emoji
*/
this.client.emit(Events.MESSAGE_REACTION_ADD, reaction, user);
return { message, reaction, user };
}
}
/**
* Emitted whenever a reaction is added to a message.
* @event Client#messageReactionAdd
* @param {MessageReaction} messageReaction The reaction object
* @param {User} user The user that applied the emoji or reaction emoji
*/
module.exports = MessageReactionAdd;

View File

@@ -1,37 +1,45 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
/*
{ user_id: 'id',
message_id: 'id',
emoji: { name: '<27>', id: null },
channel_id: 'id' } }
channel_id: 'id',
guild_id: 'id' }
*/
class MessageReactionRemove extends Action {
handle(data) {
const user = this.client.users.get(data.user_id);
if (!user) return false;
// Verify channel
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
// Verify message
const message = channel.messages.get(data.message_id);
if (!message) return false;
if (!data.emoji) return false;
const user = this.getUser(data);
if (!user) return false;
// Verify channel
const channel = this.getChannel(data);
if (!channel || channel.type === 'voice') return false;
// Verify message
const message = this.getMessage(data, channel);
if (!message) return false;
// Verify reaction
const reaction = message._removeReaction(data.emoji, user);
if (reaction) this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE, reaction, user);
const reaction = this.getReaction(data, message, user);
if (!reaction) return false;
reaction._remove(user);
/**
* Emitted whenever a reaction is removed from a cached message.
* @event Client#messageReactionRemove
* @param {MessageReaction} messageReaction The reaction object
* @param {User} user The user whose emoji or reaction emoji was removed
*/
this.client.emit(Events.MESSAGE_REACTION_REMOVE, reaction, user);
return { message, reaction, user };
}
}
/**
* Emitted whenever a reaction is removed from a message.
* @event Client#messageReactionRemove
* @param {MessageReaction} messageReaction The reaction object
* @param {User} user The user that removed the emoji or reaction emoji
*/
module.exports = MessageReactionRemove;

View File

@@ -1,23 +1,27 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const { Events } = require('../../util/Constants');
class MessageReactionRemoveAll extends Action {
handle(data) {
const channel = this.client.channels.get(data.channel_id);
// Verify channel
const channel = this.getChannel(data);
if (!channel || channel.type === 'voice') return false;
const message = channel.messages.get(data.message_id);
// Verify message
const message = this.getMessage(data, channel);
if (!message) return false;
message._clearReactions();
this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE_ALL, message);
message.reactions.cache.clear();
this.client.emit(Events.MESSAGE_REACTION_REMOVE_ALL, message);
return { message };
}
}
/**
* Emitted whenever all reactions are removed from a message.
* Emitted whenever all reactions are removed from a cached message.
* @event Client#messageReactionRemoveAll
* @param {Message} message The message the reactions were removed from
*/

View File

@@ -0,0 +1,28 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class MessageReactionRemoveEmoji extends Action {
handle(data) {
const channel = this.getChannel(data);
if (!channel || channel.type === 'voice') return false;
const message = this.getMessage(data, channel);
if (!message) return false;
const reaction = this.getReaction(data, message);
if (!reaction) return false;
if (!message.partial) message.reactions.cache.delete(reaction.emoji.id || reaction.emoji.name);
/**
* Emitted when a bot removes an emoji reaction from a cached message.
* @event Client#messageReactionRemoveEmoji
* @param {MessageReaction} reaction The reaction that was removed
*/
this.client.emit(Events.MESSAGE_REACTION_REMOVE_EMOJI, reaction);
return { reaction };
}
}
module.exports = MessageReactionRemoveEmoji;

View File

@@ -1,40 +1,24 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
class MessageUpdateAction extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.get(data.channel_id);
const channel = this.getChannel(data);
if (channel) {
const message = channel.messages.get(data.id);
const { id, channel_id, guild_id, author, timestamp, type } = data;
const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel);
if (message) {
message.patch(data);
client.emit(Constants.Events.MESSAGE_UPDATE, message._edits[0], message);
const old = message.patch(data);
return {
old: message._edits[0],
old,
updated: message,
};
}
return {
old: message,
updated: message,
};
}
return {
old: null,
updated: null,
};
return {};
}
}
/**
* Emitted whenever a message is updated - e.g. embed or content change.
* @event Client#messageUpdate
* @param {Message} oldMessage The message before the update
* @param {Message} newMessage The message after the update
*/
module.exports = MessageUpdateAction;

View File

@@ -0,0 +1,44 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class PresenceUpdateAction extends Action {
handle(data) {
let user = this.client.users.cache.get(data.user.id);
if (!user && data.user.username) user = this.client.users.add(data.user);
if (!user) return;
if (data.user && data.user.username) {
if (!user.equals(data.user)) this.client.actions.UserUpdate.handle(data.user);
}
const guild = this.client.guilds.cache.get(data.guild_id);
if (!guild) return;
let oldPresence = guild.presences.cache.get(user.id);
if (oldPresence) oldPresence = oldPresence._clone();
let member = guild.members.cache.get(user.id);
if (!member && data.status !== 'offline') {
member = guild.members.add({
user,
roles: data.roles,
deaf: false,
mute: false,
});
this.client.emit(Events.GUILD_MEMBER_AVAILABLE, member);
}
guild.presences.add(Object.assign(data, { guild }));
if (member && this.client.listenerCount(Events.PRESENCE_UPDATE)) {
/**
* Emitted whenever a guild member's presence (e.g. status, activity) is changed.
* @event Client#presenceUpdate
* @param {?Presence} oldPresence The presence before the update, if one at all
* @param {Presence} newPresence The presence after the update
*/
this.client.emit(Events.PRESENCE_UPDATE, oldPresence, member.presence);
}
}
}
module.exports = PresenceUpdateAction;

View File

@@ -0,0 +1,58 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
const textBasedChannelTypes = ['dm', 'text', 'news'];
class TypingStart extends Action {
handle(data) {
const channel = this.getChannel(data);
if (!channel) {
return;
}
if (!textBasedChannelTypes.includes(channel.type)) {
this.client.emit(Events.WARN, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`);
return;
}
const user = this.getUserFromMember(data);
const timestamp = new Date(data.timestamp * 1000);
if (channel && user) {
if (channel._typing.has(user.id)) {
const typing = channel._typing.get(user.id);
typing.lastTimestamp = timestamp;
typing.elapsedTime = Date.now() - typing.since;
this.client.clearTimeout(typing.timeout);
typing.timeout = this.tooLate(channel, user);
} else {
const since = new Date();
const lastTimestamp = new Date();
channel._typing.set(user.id, {
user,
since,
lastTimestamp,
elapsedTime: Date.now() - since,
timeout: this.tooLate(channel, user),
});
/**
* Emitted whenever a user starts typing in a channel.
* @event Client#typingStart
* @param {Channel} channel The channel the user started typing in
* @param {User} user The user that started typing
*/
this.client.emit(Events.TYPING_START, channel, user);
}
}
}
tooLate(channel, user) {
return channel.client.setTimeout(() => {
channel._typing.delete(user.id);
}, 10000);
}
}
module.exports = TypingStart;

View File

@@ -1,11 +0,0 @@
const Action = require('./Action');
class UserGetAction extends Action {
handle(data) {
const client = this.client;
const user = client.dataManager.newUser(data);
return { user };
}
}
module.exports = UserGetAction;

View File

@@ -1,30 +0,0 @@
const Action = require('./Action');
const Constants = require('../../util/Constants');
class UserNoteUpdateAction extends Action {
handle(data) {
const client = this.client;
const oldNote = client.user.notes.get(data.id);
const note = data.note.length ? data.note : null;
client.user.notes.set(data.id, note);
client.emit(Constants.Events.USER_NOTE_UPDATE, data.id, oldNote, note);
return {
old: oldNote,
updated: note,
};
}
}
/**
* Emitted whenever a note is updated.
* @event Client#userNoteUpdate
* @param {User} user The user the note belongs to
* @param {string} oldNote The note content before the update
* @param {string} newNote The note content after the update
*/
module.exports = UserNoteUpdateAction;

View File

@@ -1,25 +1,27 @@
'use strict';
const Action = require('./Action');
const Constants = require('../../util/Constants');
const Util = require('../../util/Util');
const { Events } = require('../../util/Constants');
class UserUpdateAction extends Action {
handle(data) {
const client = this.client;
if (client.user) {
if (client.user.equals(data)) {
return {
old: client.user,
updated: client.user,
};
}
const newUser = client.users.cache.get(data.id);
const oldUser = newUser._update(data);
const oldUser = Util.cloneObject(client.user);
client.user.patch(data);
client.emit(Constants.Events.USER_UPDATE, oldUser, client.user);
if (!oldUser.equals(newUser)) {
/**
* Emitted whenever a user's details (e.g. username) are changed.
* Triggered by the Discord gateway events USER_UPDATE, GUILD_MEMBER_UPDATE, and PRESENCE_UPDATE.
* @event Client#userUpdate
* @param {User} oldUser The user before the update
* @param {User} newUser The user after the update
*/
client.emit(Events.USER_UPDATE, oldUser, newUser);
return {
old: oldUser,
updated: client.user,
updated: newUser,
};
}

View File

@@ -0,0 +1,45 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
const Structures = require('../../util/Structures');
class VoiceStateUpdate extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.cache.get(data.guild_id);
if (guild) {
const VoiceState = Structures.get('VoiceState');
// Update the state
const oldState = guild.voiceStates.cache.has(data.user_id)
? guild.voiceStates.cache.get(data.user_id)._clone()
: new VoiceState(guild, { user_id: data.user_id });
const newState = guild.voiceStates.add(data);
// Get the member
let member = guild.members.cache.get(data.user_id);
if (member && data.member) {
member._patch(data.member);
} else if (data.member && data.member.user && data.member.joined_at) {
member = guild.members.add(data.member);
}
// Emit event
if (member && member.user.id === client.user.id) {
client.emit('debug', `[VOICE] received voice state update: ${JSON.stringify(data)}`);
client.voice.onVoiceStateUpdate(data);
}
/**
* Emitted whenever a member changes voice state - e.g. joins/leaves a channel, mutes/unmutes.
* @event Client#voiceStateUpdate
* @param {VoiceState} oldState The voice state before the update
* @param {VoiceState} newState The voice state after the update
*/
client.emit(Events.VOICE_STATE_UPDATE, oldState, newState);
}
}
}
module.exports = VoiceStateUpdate;

View File

@@ -0,0 +1,19 @@
'use strict';
const Action = require('./Action');
const { Events } = require('../../util/Constants');
class WebhooksUpdate extends Action {
handle(data) {
const client = this.client;
const channel = client.channels.cache.get(data.channel_id);
/**
* Emitted whenever a guild text channel has its webhooks changed.
* @event Client#webhookUpdate
* @param {TextChannel} channel The channel that had a webhook update
*/
if (channel) client.emit(Events.WEBHOOKS_UPDATE, channel);
}
}
module.exports = WebhooksUpdate;

View File

@@ -1,52 +0,0 @@
const snekfetch = require('snekfetch');
const Constants = require('../../util/Constants');
class APIRequest {
constructor(rest, method, path, auth, data, files, reason) {
this.rest = rest;
this.client = rest.client;
this.method = method;
this.path = path.toString();
this.auth = auth;
this.data = data;
this.files = files;
this.route = this.getRoute(this.path);
this.reason = reason;
}
getRoute(url) {
let route = url.split('?')[0];
if (route.includes('/channels/') || route.includes('/guilds/')) {
const startInd = route.includes('/channels/') ? route.indexOf('/channels/') : route.indexOf('/guilds/');
const majorID = route.substring(startInd).split('/')[2];
route = route.replace(/(\d{8,})/g, ':id').replace(':id', majorID);
}
return route;
}
getAuth() {
if (this.client.token && this.client.user && this.client.user.bot) {
return `Bot ${this.client.token}`;
} else if (this.client.token) {
return this.client.token;
}
throw new Error(Constants.Errors.NO_TOKEN);
}
gen() {
const API = `${this.client.options.http.host}/api/v${this.client.options.http.version}`;
const request = snekfetch[this.method](`${API}${this.path}`);
if (this.auth) request.set('Authorization', this.getAuth());
if (this.reason) request.set('X-Audit-Log-Reason', encodeURIComponent(this.reason));
if (!this.rest.client.browser) request.set('User-Agent', this.rest.userAgentManager.userAgent);
if (this.files) {
for (const file of this.files) if (file && file.file) request.attach(file.name, file.file, file.name);
if (typeof this.data !== 'undefined') request.attach('payload_json', JSON.stringify(this.data));
} else if (this.data) {
request.send(this.data);
}
return request;
}
}
module.exports = APIRequest;

View File

@@ -1,56 +0,0 @@
const UserAgentManager = require('./UserAgentManager');
const RESTMethods = require('./RESTMethods');
const SequentialRequestHandler = require('./RequestHandlers/Sequential');
const BurstRequestHandler = require('./RequestHandlers/Burst');
const APIRequest = require('./APIRequest');
const Constants = require('../../util/Constants');
class RESTManager {
constructor(client) {
this.client = client;
this.handlers = {};
this.userAgentManager = new UserAgentManager(this);
this.methods = new RESTMethods(this);
this.rateLimitedEndpoints = {};
this.globallyRateLimited = false;
}
destroy() {
for (const handler of Object.values(this.handlers)) {
if (handler.destroy) handler.destroy();
}
}
push(handler, apiRequest) {
return new Promise((resolve, reject) => {
handler.push({
request: apiRequest,
resolve,
reject,
});
});
}
getRequestHandler() {
switch (this.client.options.apiRequestMethod) {
case 'sequential':
return SequentialRequestHandler;
case 'burst':
return BurstRequestHandler;
default:
throw new Error(Constants.Errors.INVALID_RATE_LIMIT_METHOD);
}
}
makeRequest(method, url, auth, data, file, reason) {
const apiRequest = new APIRequest(this, method, url, auth, data, file, reason);
if (!this.handlers[apiRequest.route]) {
const RequestHandlerType = this.getRequestHandler();
this.handlers[apiRequest.route] = new RequestHandlerType(this, apiRequest.route);
}
return this.push(this.handlers[apiRequest.route], apiRequest);
}
}
module.exports = RESTManager;

View File

@@ -1,964 +0,0 @@
const querystring = require('querystring');
const long = require('long');
const Permissions = require('../../util/Permissions');
const Constants = require('../../util/Constants');
const Endpoints = Constants.Endpoints;
const Collection = require('../../util/Collection');
const Util = require('../../util/Util');
const User = require('../../structures/User');
const GuildMember = require('../../structures/GuildMember');
const Message = require('../../structures/Message');
const Role = require('../../structures/Role');
const Invite = require('../../structures/Invite');
const Webhook = require('../../structures/Webhook');
const UserProfile = require('../../structures/UserProfile');
const OAuth2Application = require('../../structures/OAuth2Application');
const Channel = require('../../structures/Channel');
const GroupDMChannel = require('../../structures/GroupDMChannel');
const Guild = require('../../structures/Guild');
const VoiceRegion = require('../../structures/VoiceRegion');
const GuildAuditLogs = require('../../structures/GuildAuditLogs');
class RESTMethods {
constructor(restManager) {
this.rest = restManager;
this.client = restManager.client;
this._ackToken = null;
}
login(token = this.client.token) {
return new Promise((resolve, reject) => {
if (typeof token !== 'string') throw new Error(Constants.Errors.INVALID_TOKEN);
token = token.replace(/^Bot\s*/i, '');
this.client.manager.connectToWebSocket(token, resolve, reject);
});
}
logout() {
return this.rest.makeRequest('post', Endpoints.logout, true, {});
}
getGateway(bot = false) {
return this.rest.makeRequest('get', bot ? Endpoints.gateway.bot : Endpoints.gateway, true);
}
fetchVoiceRegions(guildID) {
let endpoint;
if (guildID) endpoint = Endpoints.Guild(guildID).voiceRegions;
else endpoint = Endpoints.voiceRegions;
return this.rest.makeRequest('get', endpoint, true).then(res => {
const regions = new Collection();
for (const region of res) regions.set(region.id, new VoiceRegion(region));
return regions;
});
}
sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code, reply } = {}, files = null) {
return new Promise((resolve, reject) => { // eslint-disable-line complexity
if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content);
// The nonce has to be a uint64 :<
if (typeof nonce !== 'undefined') {
nonce = parseInt(nonce);
if (isNaN(nonce) || nonce < 0) throw new RangeError('Message nonce must fit in an unsigned 64-bit integer.');
}
if (content) {
if (split && typeof split !== 'object') split = {};
// Wrap everything in a code block
if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) {
content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``;
if (split) {
split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`;
split.append = '\n```';
}
}
// Add zero-width spaces to @everyone/@here
if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) {
content = content.replace(/@(everyone|here)/g, '@\u200b$1');
}
// Add the reply prefix
if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
const id = this.client.resolver.resolveUserID(reply);
const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
content = `${mention}${content ? `, ${content}` : ''}`;
if (split) split.prepend = `${mention}, ${split.prepend || ''}`;
}
// Split the content
if (split) content = Util.splitMessage(content, split);
} else if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
const id = this.client.resolver.resolveUserID(reply);
content = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
}
const send = chan => {
if (content instanceof Array) {
const messages = [];
(function sendChunk(list, index) {
const options = index === list.length - 1 ? { tts, embed, files } : { tts };
chan.send(list[index], options).then(message => {
messages.push(message);
if (index >= list.length - 1) return resolve(messages);
return sendChunk(list, ++index);
}).catch(reject);
}(content, 0));
} else {
this.rest.makeRequest('post', Endpoints.Channel(chan).messages, true, {
content, tts, nonce, embed,
}, files).then(data => resolve(this.client.actions.MessageCreate.handle(data).message), reject);
}
};
if (channel instanceof User || channel instanceof GuildMember) this.createDM(channel).then(send, reject);
else send(channel);
});
}
updateMessage(message, content, { embed, code, reply } = {}) {
if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content);
// Wrap everything in a code block
if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) {
content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``;
}
// Add the reply prefix
if (reply && message.channel.type !== 'dm') {
const id = this.client.resolver.resolveUserID(reply);
const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
content = `${mention}${content ? `, ${content}` : ''}`;
}
return this.rest.makeRequest('patch', Endpoints.Message(message), true, {
content, embed,
}).then(data => this.client.actions.MessageUpdate.handle(data).updated);
}
deleteMessage(message) {
return this.rest.makeRequest('delete', Endpoints.Message(message), true)
.then(() =>
this.client.actions.MessageDelete.handle({
id: message.id,
channel_id: message.channel.id,
}).message
);
}
ackMessage(message) {
return this.rest.makeRequest('post', Endpoints.Message(message).ack, true, { token: this._ackToken }).then(res => {
if (res.token) this._ackToken = res.token;
return message;
});
}
ackTextChannel(channel) {
return this.rest.makeRequest('post', Endpoints.Channel(channel).Message(channel.lastMessageID).ack, true, {
token: this._ackToken,
}).then(res => {
if (res.token) this._ackToken = res.token;
return channel;
});
}
ackGuild(guild) {
return this.rest.makeRequest('post', Endpoints.Guild(guild).ack, true).then(() => guild);
}
bulkDeleteMessages(channel, messages) {
return this.rest.makeRequest('post', Endpoints.Channel(channel).messages.bulkDelete, true, {
messages: messages.map(m => m.id),
}).then(() =>
this.client.actions.MessageDeleteBulk.handle({
channel_id: channel.id,
messages,
}).messages
);
}
search(target, options) {
if (typeof options === 'string') options = { content: options };
if (options.before) {
if (!(options.before instanceof Date)) options.before = new Date(options.before);
options.maxID = long.fromNumber(options.before.getTime() - 14200704e5).shiftLeft(22).toString();
}
if (options.after) {
if (!(options.after instanceof Date)) options.after = new Date(options.after);
options.minID = long.fromNumber(options.after.getTime() - 14200704e5).shiftLeft(22).toString();
}
if (options.during) {
if (!(options.during instanceof Date)) options.during = new Date(options.during);
const t = options.during.getTime() - 14200704e5;
options.minID = long.fromNumber(t).shiftLeft(22).toString();
options.maxID = long.fromNumber(t + 86400000).shiftLeft(22).toString();
}
if (options.channel) options.channel = this.client.resolver.resolveChannelID(options.channel);
if (options.author) options.author = this.client.resolver.resolveUserID(options.author);
if (options.mentions) options.mentions = this.client.resolver.resolveUserID(options.options.mentions);
options = {
content: options.content,
max_id: options.maxID,
min_id: options.minID,
has: options.has,
channel_id: options.channel,
author_id: options.author,
author_type: options.authorType,
context_size: options.contextSize,
sort_by: options.sortBy,
sort_order: options.sortOrder,
limit: options.limit,
offset: options.offset,
mentions: options.mentions,
mentions_everyone: options.mentionsEveryone,
link_hostname: options.linkHostname,
embed_provider: options.embedProvider,
embed_type: options.embedType,
attachment_filename: options.attachmentFilename,
attachment_extension: options.attachmentExtension,
include_nsfw: options.nsfw,
};
for (const key in options) if (options[key] === undefined) delete options[key];
const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
let endpoint;
if (target instanceof Channel) {
endpoint = Endpoints.Channel(target).search;
} else if (target instanceof Guild) {
endpoint = Endpoints.Guild(target).search;
} else {
throw new TypeError('Target must be a TextChannel, DMChannel, GroupDMChannel, or Guild.');
}
return this.rest.makeRequest('get', `${endpoint}?${queryString}`, true).then(body => {
const messages = body.messages.map(x =>
x.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client))
);
return {
totalResults: body.total_results,
messages,
};
});
}
createChannel(guild, channelName, channelType, overwrites, reason) {
if (overwrites instanceof Collection || overwrites instanceof Array) {
overwrites = overwrites.map(overwrite => {
let allow = overwrite.allow || overwrite._allowed;
let deny = overwrite.deny || overwrite._denied;
if (allow instanceof Array) allow = Permissions.resolve(allow);
if (deny instanceof Array) deny = Permissions.resolve(deny);
const role = this.client.resolver.resolveRole(guild, overwrite.id);
if (role) {
overwrite.id = role.id;
overwrite.type = 'role';
} else {
overwrite.id = this.client.resolver.resolveUserID(overwrite.id);
overwrite.type = 'member';
}
return {
allow,
deny,
type: overwrite.type,
id: overwrite.id,
};
});
}
return this.rest.makeRequest('post', Endpoints.Guild(guild).channels, true, {
name: channelName,
type: channelType ? Constants.ChannelTypes[channelType.toUpperCase()] : 'text',
permission_overwrites: overwrites,
}, undefined, reason).then(data => this.client.actions.ChannelCreate.handle(data).channel);
}
createDM(recipient) {
const dmChannel = this.getExistingDM(recipient);
if (dmChannel) return Promise.resolve(dmChannel);
return this.rest.makeRequest('post', Endpoints.User(this.client.user).channels, true, {
recipient_id: recipient.id,
}).then(data => this.client.actions.ChannelCreate.handle(data).channel);
}
createGroupDM(options) {
const data = this.client.user.bot ?
{ access_tokens: options.accessTokens, nicks: options.nicks } :
{ recipients: options.recipients };
return this.rest.makeRequest('post', Endpoints.User('@me').channels, true, data)
.then(res => new GroupDMChannel(this.client, res));
}
addUserToGroupDM(channel, options) {
const data = this.client.user.bot ?
{ nick: options.nick, access_token: options.accessToken } :
{ recipient: options.id };
return this.rest.makeRequest('put', Endpoints.Channel(channel).Recipient(options.id), true, data)
.then(() => channel);
}
removeUserFromGroupDM(channel, userId) {
return this.rest.makeRequest('delete', Endpoints.Channel(channel).Recipient(userId), true)
.then(() => channel);
}
updateGroupDMChannel(channel, _data) {
const data = {};
data.name = _data.name;
data.icon = _data.icon;
return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data).then(() => channel);
}
getExistingDM(recipient) {
return this.client.channels.find(channel =>
channel.recipient && channel.recipient.id === recipient.id
);
}
deleteChannel(channel, reason) {
if (channel instanceof User || channel instanceof GuildMember) channel = this.getExistingDM(channel);
if (!channel) return Promise.reject(new Error('No channel to delete.'));
return this.rest.makeRequest('delete', Endpoints.Channel(channel), true, undefined, undefined, reason)
.then(data => {
data.id = channel.id;
return this.client.actions.ChannelDelete.handle(data).channel;
});
}
updateChannel(channel, _data, reason) {
const data = {};
data.name = (_data.name || channel.name).trim();
data.topic = _data.topic || channel.topic;
data.position = _data.position || channel.position;
data.bitrate = _data.bitrate || (channel.bitrate ? channel.bitrate * 1000 : undefined);
data.user_limit = typeof _data.userLimit !== 'undefined' ? _data.userLimit : channel.userLimit;
data.parent_id = _data.parent || (channel.parent ? channel.parent.id : undefined);
return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data, undefined, reason).then(newData =>
this.client.actions.ChannelUpdate.handle(newData).updated
);
}
leaveGuild(guild) {
if (guild.ownerID === this.client.user.id) return Promise.reject(new Error('Guild is owned by the client.'));
return this.rest.makeRequest('delete', Endpoints.User('@me').Guild(guild.id), true).then(() =>
this.client.actions.GuildDelete.handle({ id: guild.id }).guild
);
}
createGuild(options) {
options.icon = this.client.resolver.resolveBase64(options.icon) || null;
options.region = options.region || 'us-central';
return new Promise((resolve, reject) => {
this.rest.makeRequest('post', Endpoints.guilds, true, options).then(data => {
if (this.client.guilds.has(data.id)) return resolve(this.client.guilds.get(data.id));
const handleGuild = guild => {
if (guild.id === data.id) {
this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild);
this.client.clearTimeout(timeout);
resolve(guild);
}
};
this.client.on(Constants.Events.GUILD_CREATE, handleGuild);
const timeout = this.client.setTimeout(() => {
this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild);
reject(new Error('Took too long to receive guild data.'));
}, 10000);
return undefined;
}, reject);
});
}
// Untested but probably will work
deleteGuild(guild) {
return this.rest.makeRequest('delete', Endpoints.Guild(guild), true).then(() =>
this.client.actions.GuildDelete.handle({ id: guild.id }).guild
);
}
getUser(userID, cache) {
return this.rest.makeRequest('get', Endpoints.User(userID), true).then(data => {
if (cache) return this.client.actions.UserGet.handle(data).user;
else return new User(this.client, data);
});
}
updateCurrentUser(_data, password) {
const user = this.client.user;
const data = {};
data.username = _data.username || user.username;
data.avatar = typeof _data.avatar === 'undefined' ? user.avatar : this.client.resolver.resolveBase64(_data.avatar);
if (!user.bot) {
data.email = _data.email || user.email;
data.password = password;
if (_data.new_password) data.new_password = _data.newPassword;
}
return this.rest.makeRequest('patch', Endpoints.User('@me'), true, data).then(newData =>
this.client.actions.UserUpdate.handle(newData).updated
);
}
updateGuild(guild, data, reason) {
return this.rest.makeRequest('patch', Endpoints.Guild(guild), true, data, undefined, reason).then(newData =>
this.client.actions.GuildUpdate.handle(newData).updated
);
}
kickGuildMember(guild, member, reason) {
return this.rest.makeRequest(
'delete', Endpoints.Guild(guild).Member(member), true,
undefined, undefined, reason)
.then(() =>
this.client.actions.GuildMemberRemove.handle({
guild_id: guild.id,
user: member.user,
}).member
);
}
createGuildRole(guild, data, reason) {
if (data.color) data.color = this.client.resolver.resolveColor(data.color);
if (data.permissions) data.permissions = Permissions.resolve(data.permissions);
return this.rest.makeRequest('post', Endpoints.Guild(guild).roles, true, data, undefined, reason).then(r => {
const { role } = this.client.actions.GuildRoleCreate.handle({
guild_id: guild.id,
role: r,
});
if (data.position) return role.setPosition(data.position, reason);
return role;
});
}
deleteGuildRole(role, reason) {
return this.rest.makeRequest(
'delete', Endpoints.Guild(role.guild).Role(role.id), true,
undefined, undefined, reason)
.then(() =>
this.client.actions.GuildRoleDelete.handle({
guild_id: role.guild.id,
role_id: role.id,
}).role
);
}
setChannelOverwrite(channel, payload) {
return this.rest.makeRequest('put', `${Endpoints.Channel(channel).permissions}/${payload.id}`, true, payload);
}
deletePermissionOverwrites(overwrite, reason) {
return this.rest.makeRequest(
'delete', `${Endpoints.Channel(overwrite.channel).permissions}/${overwrite.id}`,
true, undefined, undefined, reason
).then(() => overwrite);
}
getChannelMessages(channel, payload = {}) {
const params = [];
if (payload.limit) params.push(`limit=${payload.limit}`);
if (payload.around) params.push(`around=${payload.around}`);
else if (payload.before) params.push(`before=${payload.before}`);
else if (payload.after) params.push(`after=${payload.after}`);
let endpoint = Endpoints.Channel(channel).messages;
if (params.length > 0) endpoint += `?${params.join('&')}`;
return this.rest.makeRequest('get', endpoint, true);
}
getChannelMessage(channel, messageID) {
const msg = channel.messages.get(messageID);
if (msg) return Promise.resolve(msg);
return this.rest.makeRequest('get', Endpoints.Channel(channel).Message(messageID), true);
}
putGuildMember(guild, user, options) {
options.access_token = options.accessToken;
if (options.roles) {
const roles = options.roles;
if (roles instanceof Collection || (roles instanceof Array && roles[0] instanceof Role)) {
options.roles = roles.map(role => role.id);
}
}
return this.rest.makeRequest('put', Endpoints.Guild(guild).Member(user.id), true, options)
.then(data => this.client.actions.GuildMemberGet.handle(guild, data).member);
}
getGuildMember(guild, user, cache) {
return this.rest.makeRequest('get', Endpoints.Guild(guild).Member(user.id), true).then(data => {
if (cache) return this.client.actions.GuildMemberGet.handle(guild, data).member;
else return new GuildMember(guild, data);
});
}
updateGuildMember(member, data, reason) {
if (data.channel) {
data.channel_id = this.client.resolver.resolveChannel(data.channel).id;
data.channel = null;
}
if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role);
let endpoint = Endpoints.Member(member);
// Fix your endpoints, discord ;-;
if (member.id === this.client.user.id) {
const keys = Object.keys(data);
if (keys.length === 1 && keys[0] === 'nick') {
endpoint = Endpoints.Member(member).nickname;
}
}
return this.rest.makeRequest('patch', endpoint, true, data, undefined, reason).then(newData =>
member.guild._updateMember(member, newData).mem
);
}
addMemberRole(member, role, reason) {
return new Promise((resolve, reject) => {
if (member._roles.includes(role.id)) return resolve(member);
const listener = (oldMember, newMember) => {
if (!oldMember._roles.includes(role.id) && newMember._roles.includes(role.id)) {
this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
resolve(newMember);
}
};
this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener);
const timeout = this.client.setTimeout(() =>
this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener), 10e3);
return this.rest.makeRequest('put', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason)
.catch(err => {
this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.client.clearTimeout(timeout);
reject(err);
});
});
}
removeMemberRole(member, role, reason) {
return new Promise((resolve, reject) => {
if (!member._roles.includes(role.id)) return resolve(member);
const listener = (oldMember, newMember) => {
if (oldMember._roles.includes(role.id) && !newMember._roles.includes(role.id)) {
this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
resolve(newMember);
}
};
this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener);
const timeout = this.client.setTimeout(() =>
this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener), 10e3);
return this.rest.makeRequest('delete', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason)
.catch(err => {
this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.client.clearTimeout(timeout);
reject(err);
});
});
}
sendTyping(channelID) {
return this.rest.makeRequest('post', Endpoints.Channel(channelID).typing, true);
}
banGuildMember(guild, member, options) {
const id = this.client.resolver.resolveUserID(member);
if (!id) return Promise.reject(new Error('Couldn\'t resolve the user ID to ban.'));
const url = `${Endpoints.Guild(guild).bans}/${id}?${querystring.stringify(options)}`;
return this.rest.makeRequest('put', url, true).then(() => {
if (member instanceof GuildMember) return member;
const user = this.client.resolver.resolveUser(id);
if (user) {
member = this.client.resolver.resolveGuildMember(guild, user);
return member || user;
}
return id;
});
}
unbanGuildMember(guild, member, reason) {
return new Promise((resolve, reject) => {
const id = this.client.resolver.resolveUserID(member);
if (!id) throw new Error('Couldn\'t resolve the user ID to unban.');
const listener = (eGuild, eUser) => {
if (eGuild.id === guild.id && eUser.id === id) {
this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.client.clearTimeout(timeout);
resolve(eUser);
}
};
this.client.on(Constants.Events.GUILD_BAN_REMOVE, listener);
const timeout = this.client.setTimeout(() => {
this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
reject(new Error('Took too long to receive the ban remove event.'));
}, 10000);
this.rest.makeRequest('delete', `${Endpoints.Guild(guild).bans}/${id}`, true, undefined, undefined, reason)
.catch(err => {
this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
this.client.clearTimeout(timeout);
reject(err);
});
});
}
getGuildBans(guild) {
return this.rest.makeRequest('get', Endpoints.Guild(guild).bans, true).then(bans =>
bans.reduce((collection, ban) => {
collection.set(ban.user.id, {
reason: ban.reason,
user: this.client.dataManager.newUser(ban.user),
});
return collection;
}, new Collection())
);
}
updateGuildRole(role, _data, reason) {
const data = {};
data.name = _data.name || role.name;
data.position = typeof _data.position !== 'undefined' ? _data.position : role.position;
data.color = this.client.resolver.resolveColor(_data.color || role.color);
data.hoist = typeof _data.hoist !== 'undefined' ? _data.hoist : role.hoist;
data.mentionable = typeof _data.mentionable !== 'undefined' ? _data.mentionable : role.mentionable;
if (_data.permissions) data.permissions = Permissions.resolve(_data.permissions);
else data.permissions = role.permissions;
return this.rest.makeRequest('patch', Endpoints.Guild(role.guild).Role(role.id), true, data, undefined, reason)
.then(_role =>
this.client.actions.GuildRoleUpdate.handle({
role: _role,
guild_id: role.guild.id,
}).updated
);
}
pinMessage(message) {
return this.rest.makeRequest('put', Endpoints.Channel(message.channel).Pin(message.id), true)
.then(() => message);
}
unpinMessage(message) {
return this.rest.makeRequest('delete', Endpoints.Channel(message.channel).Pin(message.id), true)
.then(() => message);
}
getChannelPinnedMessages(channel) {
return this.rest.makeRequest('get', Endpoints.Channel(channel).pins, true);
}
createChannelInvite(channel, options, reason) {
const payload = {};
payload.temporary = options.temporary;
payload.max_age = options.maxAge;
payload.max_uses = options.maxUses;
payload.unique = options.unique;
return this.rest.makeRequest('post', Endpoints.Channel(channel).invites, true, payload, undefined, reason)
.then(invite => new Invite(this.client, invite));
}
deleteInvite(invite, reason) {
return this.rest.makeRequest('delete', Endpoints.Invite(invite.code), true, undefined, undefined, reason)
.then(() => invite);
}
getInvite(code) {
return this.rest.makeRequest('get', Endpoints.Invite(code), true).then(invite =>
new Invite(this.client, invite)
);
}
getGuildInvites(guild) {
return this.rest.makeRequest('get', Endpoints.Guild(guild).invites, true).then(inviteItems => {
const invites = new Collection();
for (const inviteItem of inviteItems) {
const invite = new Invite(this.client, inviteItem);
invites.set(invite.code, invite);
}
return invites;
});
}
pruneGuildMembers(guild, days, dry, reason) {
return this.rest.makeRequest(dry ?
'get' :
'post',
`${Endpoints.Guild(guild).prune}?days=${days}`, true, undefined, undefined, reason)
.then(data => data.pruned);
}
createEmoji(guild, image, name, roles, reason) {
const data = { image, name };
if (roles) data.roles = roles.map(r => r.id ? r.id : r);
return this.rest.makeRequest('post', Endpoints.Guild(guild).emojis, true, data, undefined, reason)
.then(emoji => this.client.actions.GuildEmojiCreate.handle(guild, emoji).emoji);
}
updateEmoji(emoji, _data, reason) {
const data = {};
if (_data.name) data.name = _data.name;
if (_data.roles) data.roles = _data.roles.map(r => r.id ? r.id : r);
return this.rest.makeRequest('patch', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, data, undefined, reason)
.then(newEmoji => this.client.actions.GuildEmojiUpdate.handle(emoji, newEmoji).emoji);
}
deleteEmoji(emoji, reason) {
return this.rest.makeRequest('delete', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, undefined, reason)
.then(() => this.client.actions.GuildEmojiDelete.handle(emoji).data);
}
getGuildAuditLogs(guild, options = {}) {
if (options.before && options.before instanceof GuildAuditLogs.Entry) options.before = options.before.id;
if (options.after && options.after instanceof GuildAuditLogs.Entry) options.after = options.after.id;
if (typeof options.type === 'string') options.type = GuildAuditLogs.Actions[options.type];
const queryString = (querystring.stringify({
before: options.before,
after: options.after,
limit: options.limit,
user_id: this.client.resolver.resolveUserID(options.user),
action_type: options.type,
}).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
return this.rest.makeRequest('get', `${Endpoints.Guild(guild).auditLogs}?${queryString}`, true)
.then(data => GuildAuditLogs.build(guild, data));
}
getWebhook(id, token) {
return this.rest.makeRequest('get', Endpoints.Webhook(id, token), !token).then(data =>
new Webhook(this.client, data)
);
}
getGuildWebhooks(guild) {
return this.rest.makeRequest('get', Endpoints.Guild(guild).webhooks, true).then(data => {
const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
return hooks;
});
}
getChannelWebhooks(channel) {
return this.rest.makeRequest('get', Endpoints.Channel(channel).webhooks, true).then(data => {
const hooks = new Collection();
for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
return hooks;
});
}
createWebhook(channel, name, avatar, reason) {
return this.rest.makeRequest('post', Endpoints.Channel(channel).webhooks, true, { name, avatar }, undefined, reason)
.then(data => new Webhook(this.client, data));
}
editWebhook(webhook, name, avatar) {
return this.rest.makeRequest('patch', Endpoints.Webhook(webhook.id, webhook.token), false, {
name,
avatar,
}).then(data => {
webhook.name = data.name;
webhook.avatar = data.avatar;
return webhook;
});
}
deleteWebhook(webhook, reason) {
return this.rest.makeRequest(
'delete', Endpoints.Webhook(webhook.id, webhook.token),
false, undefined, undefined, reason);
}
sendWebhookMessage(webhook, content, { avatarURL, tts, embeds, username } = {}, files = null) {
return new Promise((resolve, reject) => {
username = username || webhook.name;
if (content instanceof Array) {
const messages = [];
(function sendChunk(list, index) {
const options = index === list.length - 1 ? { tts, embeds, files } : { tts };
webhook.send(list[index], options).then(message => {
messages.push(message);
if (index >= list.length - 1) return resolve(messages);
return sendChunk(list, ++index);
}).catch(reject);
}(content, 0));
} else {
this.rest.makeRequest('post', `${Endpoints.Webhook(webhook.id, webhook.token)}?wait=true`, false, {
username,
avatar_url: avatarURL,
content,
tts,
embeds,
}, files).then(data => {
if (!this.client.channels) resolve(data);
else resolve(this.client.actions.MessageCreate.handle(data).message);
}, reject);
}
});
}
sendSlackWebhookMessage(webhook, body) {
return this.rest.makeRequest(
'post', `${Endpoints.Webhook(webhook.id, webhook.token)}/slack?wait=true`, false, body
);
}
fetchUserProfile(user) {
return this.rest.makeRequest('get', Endpoints.User(user).profile, true).then(data =>
new UserProfile(user, data)
);
}
fetchMentions(options) {
if (options.guild instanceof Guild) options.guild = options.guild.id;
Util.mergeDefault({ limit: 25, roles: true, everyone: true, guild: null }, options);
return this.rest.makeRequest(
'get', Endpoints.User('@me').Mentions(options.limit, options.roles, options.everyone, options.guild), true
).then(data => data.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client)));
}
addFriend(user) {
return this.rest.makeRequest('post', Endpoints.User('@me'), true, {
username: user.username,
discriminator: user.discriminator,
}).then(() => user);
}
removeFriend(user) {
return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true)
.then(() => user);
}
blockUser(user) {
return this.rest.makeRequest('put', Endpoints.User('@me').Relationship(user.id), true, { type: 2 })
.then(() => user);
}
unblockUser(user) {
return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true)
.then(() => user);
}
updateChannelPositions(guildID, channels) {
const data = new Array(channels.length);
for (let i = 0; i < channels.length; i++) {
data[i] = {
id: this.client.resolver.resolveChannelID(channels[i].channel),
position: channels[i].position,
};
}
return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, data).then(() =>
this.client.actions.GuildChannelsPositionUpdate.handle({
guild_id: guildID,
channels,
}).guild
);
}
setRolePositions(guildID, roles) {
return this.rest.makeRequest('patch', Endpoints.Guild(guildID).roles, true, roles).then(() =>
this.client.actions.GuildRolesPositionUpdate.handle({
guild_id: guildID,
roles,
}).guild
);
}
setChannelPositions(guildID, channels) {
return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, channels).then(() =>
this.client.actions.GuildChannelsPositionUpdate.handle({
guild_id: guildID,
channels,
}).guild
);
}
addMessageReaction(message, emoji) {
return this.rest.makeRequest(
'put', Endpoints.Message(message).Reaction(emoji).User('@me'), true
).then(() =>
message._addReaction(Util.parseEmoji(emoji), message.client.user)
);
}
removeMessageReaction(message, emoji, userID) {
const endpoint = Endpoints.Message(message).Reaction(emoji).User(userID === this.client.user.id ? '@me' : userID);
return this.rest.makeRequest('delete', endpoint, true).then(() =>
this.client.actions.MessageReactionRemove.handle({
user_id: userID,
message_id: message.id,
emoji: Util.parseEmoji(emoji),
channel_id: message.channel.id,
}).reaction
);
}
removeMessageReactions(message) {
return this.rest.makeRequest('delete', Endpoints.Message(message).reactions, true)
.then(() => message);
}
getMessageReactionUsers(message, emoji, options) {
const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
return this.rest.makeRequest('get', `${Endpoints.Message(message).Reaction(emoji)}?${queryString}`, true);
}
getApplication(id) {
return this.rest.makeRequest('get', Endpoints.OAUTH2.Application(id), true).then(app =>
new OAuth2Application(this.client, app)
);
}
resetApplication(id) {
return this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetToken, true)
.then(() => this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetSecret, true))
.then(app => new OAuth2Application(this.client, app));
}
setNote(user, note) {
return this.rest.makeRequest('put', Endpoints.User(user).note, true, { note }).then(() => user);
}
acceptInvite(code) {
if (code.id) code = code.id;
return new Promise((resolve, reject) =>
this.rest.makeRequest('post', Endpoints.Invite(code), true).then(res => {
const handler = guild => {
if (guild.id === res.id) {
resolve(guild);
this.client.removeListener(Constants.Events.GUILD_CREATE, handler);
}
};
this.client.on(Constants.Events.GUILD_CREATE, handler);
this.client.setTimeout(() => {
this.client.removeListener(Constants.Events.GUILD_CREATE, handler);
reject(new Error('Accepting invite timed out'));
}, 120e3);
})
);
}
patchUserSettings(data) {
return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').settings, true, data);
}
patchClientUserGuildSettings(guildID, data) {
return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').Guild(guildID).settings, true, data);
}
}
module.exports = RESTMethods;

View File

@@ -1,71 +0,0 @@
const RequestHandler = require('./RequestHandler');
const DiscordAPIError = require('../DiscordAPIError');
class BurstRequestHandler extends RequestHandler {
constructor(restManager, endpoint) {
super(restManager, endpoint);
this.client = restManager.client;
this.limit = Infinity;
this.resetTime = null;
this.remaining = 1;
this.timeDifference = 0;
this.resetTimeout = null;
}
push(request) {
super.push(request);
this.handle();
}
execute(item) {
if (!item) return;
item.request.gen().end((err, res) => {
if (res && res.headers) {
this.limit = Number(res.headers['x-ratelimit-limit']);
this.resetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.remaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
}
if (err) {
if (err.status === 429) {
this.queue.unshift(item);
if (res.headers['x-ratelimit-global']) this.globalLimit = true;
if (this.resetTimeout) return;
this.resetTimeout = this.client.setTimeout(() => {
this.remaining = this.limit;
this.globalLimit = false;
this.handle();
this.resetTimeout = null;
}, Number(res.headers['retry-after']) + this.client.options.restTimeOffset);
} else if (err.status >= 500 && err.status < 600) {
this.queue.unshift(item);
this.resetTimeout = this.client.setTimeout(() => {
this.handle();
this.resetTimeout = null;
}, 1e3 + this.client.options.restTimeOffset);
} else {
item.reject(err.status >= 400 && err.status < 500 ? new DiscordAPIError(res.request.path, res.body) : err);
this.handle();
}
} else {
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
this.handle();
}
});
}
handle() {
super.handle();
if (this.remaining <= 0 || this.queue.length === 0 || this.globalLimit) return;
this.execute(this.queue.shift());
this.remaining--;
this.handle();
}
}
module.exports = BurstRequestHandler;

View File

@@ -1,54 +0,0 @@
/**
* A base class for different types of rate limiting handlers for the REST API.
* @private
*/
class RequestHandler {
/**
* @param {RESTManager} restManager The REST manager to use
*/
constructor(restManager) {
/**
* The RESTManager that instantiated this RequestHandler
* @type {RESTManager}
*/
this.restManager = restManager;
/**
* A list of requests that have yet to be processed
* @type {APIRequest[]}
*/
this.queue = [];
}
/**
* Whether or not the client is being rate limited on every endpoint
* @type {boolean}
* @readonly
*/
get globalLimit() {
return this.restManager.globallyRateLimited;
}
set globalLimit(value) {
this.restManager.globallyRateLimited = value;
}
/**
* Push a new API request into this bucket.
* @param {APIRequest} request The new request to push into the queue
*/
push(request) {
this.queue.push(request);
}
/**
* Attempts to get this RequestHandler to process its current queue.
*/
handle() {} // eslint-disable-line no-empty-function
destroy() {
this.queue = [];
}
}
module.exports = RequestHandler;

View File

@@ -1,101 +0,0 @@
const RequestHandler = require('./RequestHandler');
const DiscordAPIError = require('../DiscordAPIError');
/**
* Handles API Requests sequentially, i.e. we wait until the current request is finished before moving onto
* the next. This plays a _lot_ nicer in terms of avoiding 429's when there is more than one session of the account,
* but it can be slower.
* @extends {RequestHandler}
* @private
*/
class SequentialRequestHandler extends RequestHandler {
/**
* @param {RESTManager} restManager The REST manager to use
* @param {string} endpoint The endpoint to handle
*/
constructor(restManager, endpoint) {
super(restManager, endpoint);
/**
* The endpoint that this handler is handling
* @type {string}
*/
this.endpoint = endpoint;
/**
* The time difference between Discord's Dates and the local computer's Dates. A positive number means the local
* computer's time is ahead of Discord's
* @type {number}
*/
this.timeDifference = 0;
/**
* Whether the queue is being processed or not
* @type {boolean}
*/
this.busy = false;
}
push(request) {
super.push(request);
this.handle();
}
/**
* Performs a request then resolves a promise to indicate its readiness for a new request.
* @param {APIRequest} item The item to execute
* @returns {Promise<?Object|Error>}
*/
execute(item) {
this.busy = true;
return new Promise(resolve => {
item.request.gen().end((err, res) => {
if (res && res.headers) {
this.requestLimit = Number(res.headers['x-ratelimit-limit']);
this.requestResetTime = Number(res.headers['x-ratelimit-reset']) * 1000;
this.requestRemaining = Number(res.headers['x-ratelimit-remaining']);
this.timeDifference = Date.now() - new Date(res.headers.date).getTime();
}
if (err) {
if (err.status === 429) {
this.queue.unshift(item);
this.restManager.client.setTimeout(() => {
this.globalLimit = false;
resolve();
}, Number(res.headers['retry-after']) + this.restManager.client.options.restTimeOffset);
if (res.headers['x-ratelimit-global']) this.globalLimit = true;
} else if (err.status >= 500 && err.status < 600) {
this.queue.unshift(item);
this.restManager.client.setTimeout(resolve, 1e3 + this.restManager.client.options.restTimeOffset);
} else {
item.reject(err.status >= 400 && err.status < 500 ? new DiscordAPIError(res.request.path, res.body) : err);
resolve(err);
}
} else {
this.globalLimit = false;
const data = res && res.body ? res.body : {};
item.resolve(data);
if (this.requestRemaining === 0) {
this.restManager.client.setTimeout(
() => resolve(data),
this.requestResetTime - Date.now() + this.timeDifference + this.restManager.client.options.restTimeOffset
);
} else {
resolve(data);
}
}
});
});
}
handle() {
super.handle();
if (this.busy || this.remaining === 0 || this.queue.length === 0 || this.globalLimit) return;
this.execute(this.queue.shift()).then(() => {
this.busy = false;
this.handle();
});
}
}
module.exports = SequentialRequestHandler;

View File

@@ -1,25 +0,0 @@
const Constants = require('../../util/Constants');
class UserAgentManager {
constructor() {
this.build(this.constructor.DEFAULT);
}
set({ url, version } = {}) {
this.build({
url: url || this.constructor.DFEAULT.url,
version: version || this.constructor.DEFAULT.version,
});
}
build(ua) {
this.userAgent = `DiscordBot (${ua.url}, ${ua.version}) Node.js/${process.version}`;
}
}
UserAgentManager.DEFAULT = {
url: Constants.Package.homepage.split('#')[0],
version: Constants.Package.version,
};
module.exports = UserAgentManager;

View File

@@ -1,17 +1,22 @@
const Collection = require('../../util/Collection');
'use strict';
const VoiceBroadcast = require('./VoiceBroadcast');
const VoiceConnection = require('./VoiceConnection');
const { Error } = require('../../errors');
const Collection = require('../../util/Collection');
/**
* Manages all the voice stuff for the client.
* @private
* Manages voice connections for the client
*/
class ClientVoiceManager {
constructor(client) {
/**
* The client that instantiated this voice manager
* @type {Client}
* @readonly
* @name ClientVoiceManager#client
*/
this.client = client;
Object.defineProperty(this, 'client', { value: client });
/**
* A collection mapping connection IDs to the Connection objects
@@ -19,36 +24,52 @@ class ClientVoiceManager {
*/
this.connections = new Collection();
this.client.on('self.voiceServer', this.onVoiceServer.bind(this));
this.client.on('self.voiceStateUpdate', this.onVoiceStateUpdate.bind(this));
/**
* Active voice broadcasts that have been created
* @type {VoiceBroadcast[]}
*/
this.broadcasts = [];
}
/**
* Creates a voice broadcast.
* @returns {VoiceBroadcast}
*/
createBroadcast() {
const broadcast = new VoiceBroadcast(this.client);
this.broadcasts.push(broadcast);
return broadcast;
}
onVoiceServer({ guild_id, token, endpoint }) {
this.client.emit('debug', `[VOICE] voiceServer guild: ${guild_id} token: ${token} endpoint: ${endpoint}`);
const connection = this.connections.get(guild_id);
if (connection) connection.setTokenAndEndpoint(token, endpoint);
}
onVoiceStateUpdate({ guild_id, session_id, channel_id }) {
const connection = this.connections.get(guild_id);
if (connection) {
connection.channel = this.client.channels.get(channel_id);
connection.setSessionID(session_id);
this.client.emit('debug', `[VOICE] connection? ${!!connection}, ${guild_id} ${session_id} ${channel_id}`);
if (!connection) return;
if (!channel_id) {
connection._disconnect();
this.connections.delete(guild_id);
return;
}
connection.channel = this.client.channels.cache.get(channel_id);
connection.setSessionID(session_id);
}
/**
* Sets up a request to join a voice channel.
* @param {VoiceChannel} channel The voice channel to join
* @returns {Promise<VoiceConnection>}
* @private
*/
joinChannel(channel) {
return new Promise((resolve, reject) => {
if (!channel.joinable) {
if (channel.full) {
throw new Error('You do not have permission to join this voice channel; it is full.');
} else {
throw new Error('You do not have permission to join this voice channel.');
}
throw new Error('VOICE_JOIN_CHANNEL', channel.full);
}
let connection = this.connections.get(channel.guild.id);
@@ -61,6 +82,10 @@ class ClientVoiceManager {
return;
} else {
connection = new VoiceConnection(this, channel);
connection.on('debug', msg =>
this.client.emit('debug', `[VOICE (${channel.guild.id}:${connection.status})]: ${msg}`),
);
connection.authenticate();
this.connections.set(channel.guild.id, connection);
}
@@ -69,9 +94,13 @@ class ClientVoiceManager {
reject(reason);
});
connection.on('error', reject);
connection.once('authenticated', () => {
connection.once('ready', () => resolve(connection));
connection.once('error', reject);
connection.once('ready', () => {
resolve(connection);
connection.removeListener('error', reject);
});
connection.once('disconnect', () => this.connections.delete(channel.guild.id));
});
});

View File

@@ -1,31 +1,26 @@
const VolumeInterface = require('./util/VolumeInterface');
const Prism = require('prism-media');
const OpusEncoders = require('./opus/OpusEngineList');
const Collection = require('../../util/Collection');
'use strict';
const ffmpegArguments = [
'-analyzeduration', '0',
'-loglevel', '0',
'-f', 's16le',
'-ar', '48000',
'-ac', '2',
];
const EventEmitter = require('events');
const BroadcastAudioPlayer = require('./player/BroadcastAudioPlayer');
const PlayInterface = require('./util/PlayInterface');
const { Events } = require('../../util/Constants');
/**
* A voice broadcast can be played across multiple voice connections for improved shared-stream efficiency.
*
* Example usage:
* ```js
* const broadcast = client.createVoiceBroadcast();
* broadcast.playFile('./music.mp3');
* const broadcast = client.voice.createBroadcast();
* broadcast.play('./music.mp3');
* // Play "music.mp3" in all voice connections that the client is in
* for (const connection of client.voiceConnections.values()) {
* connection.playBroadcast(broadcast);
* for (const connection of client.voice.connections.values()) {
* connection.play(broadcast);
* }
* ```
* @implements {VolumeInterface}
* @implements {PlayInterface}
* @extends {EventEmitter}
*/
class VoiceBroadcast extends VolumeInterface {
class VoiceBroadcast extends EventEmitter {
constructor(client) {
super();
/**
@@ -33,334 +28,84 @@ class VoiceBroadcast extends VolumeInterface {
* @type {Client}
*/
this.client = client;
this._dispatchers = new Collection();
this._encoders = new Collection();
/**
* The audio transcoder that this broadcast uses
* @type {Prism}
* The subscribed StreamDispatchers of this broadcast
* @type {StreamDispatcher[]}
*/
this.prism = new Prism();
/**
* The current audio transcoder that is being used
* @type {Object}
*/
this.currentTranscoder = null;
this.tickInterval = null;
this._volume = 1;
this.subscribers = [];
this.player = new BroadcastAudioPlayer(this);
}
/**
* An array of subscribed dispatchers
* @type {StreamDispatcher[]}
* The current master dispatcher, if any. This dispatcher controls all that is played by subscribed dispatchers.
* @type {?BroadcastDispatcher}
* @readonly
*/
get dispatchers() {
let d = [];
for (const container of this._dispatchers.values()) {
d = d.concat(Array.from(container.values()));
}
return d;
get dispatcher() {
return this.player.dispatcher;
}
get _playableStream() {
const currentTranscoder = this.currentTranscoder;
if (!currentTranscoder) return null;
const transcoder = currentTranscoder.transcoder;
const options = currentTranscoder.options;
return (transcoder && transcoder.output) || options.stream;
/**
* Play an audio resource.
* @param {ReadableStream|string} resource The resource to play.
* @param {StreamOptions} [options] The options to play.
* @example
* // Play a local audio file
* broadcast.play('/home/hydrabolt/audio.mp3', { volume: 0.5 });
* @example
* // Play a ReadableStream
* broadcast.play(ytdl('https://www.youtube.com/watch?v=ZlAU_w7-Xp8', { filter: 'audioonly' }));
* @example
* // Using different protocols: https://ffmpeg.org/ffmpeg-protocols.html
* broadcast.play('http://www.sample-videos.com/audio/mp3/wave.mp3');
* @returns {BroadcastDispatcher}
*/
play() {
return null;
}
unregisterDispatcher(dispatcher, old) {
const volume = old || dispatcher.volume;
/**
* Emitted whenever a stream dispatcher unsubscribes from the broadcast.
* @event VoiceBroadcast#unsubscribe
* @param {StreamDispatcher} dispatcher The unsubscribed dispatcher
*/
this.emit('unsubscribe', dispatcher);
for (const container of this._dispatchers.values()) {
container.delete(dispatcher);
if (!container.size) {
this._encoders.get(volume).destroy();
this._dispatchers.delete(volume);
this._encoders.delete(volume);
}
}
/**
* Ends the broadcast, unsubscribing all subscribed channels and deleting the broadcast
*/
end() {
for (const dispatcher of this.subscribers) this.delete(dispatcher);
const index = this.client.voice.broadcasts.indexOf(this);
if (index !== -1) this.client.voice.broadcasts.splice(index, 1);
}
registerDispatcher(dispatcher) {
if (!this._dispatchers.has(dispatcher.volume)) {
this._dispatchers.set(dispatcher.volume, new Set());
this._encoders.set(dispatcher.volume, OpusEncoders.fetch());
}
const container = this._dispatchers.get(dispatcher.volume);
if (!container.has(dispatcher)) {
container.add(dispatcher);
dispatcher.once('end', () => this.unregisterDispatcher(dispatcher));
dispatcher.on('volumeChange', (o, n) => {
this.unregisterDispatcher(dispatcher, o);
if (!this._dispatchers.has(n)) {
this._dispatchers.set(n, new Set());
this._encoders.set(n, OpusEncoders.fetch());
}
this._dispatchers.get(n).add(dispatcher);
});
add(dispatcher) {
const index = this.subscribers.indexOf(dispatcher);
if (index === -1) {
this.subscribers.push(dispatcher);
/**
* Emitted whenever a stream dispatcher subscribes to the broadcast.
* @event VoiceBroadcast#subscribe
* @param {StreamDispatcher} dispatcher The subscribed dispatcher
* @param {StreamDispatcher} subscriber The subscribed dispatcher
*/
this.emit('subscribe', dispatcher);
this.emit(Events.VOICE_BROADCAST_SUBSCRIBE, dispatcher);
return true;
} else {
return false;
}
}
killCurrentTranscoder() {
if (this.currentTranscoder) {
if (this.currentTranscoder.transcoder) this.currentTranscoder.transcoder.kill();
this.currentTranscoder = null;
this.emit('end');
}
}
/**
* Plays any audio stream across the broadcast.
* @param {ReadableStream} stream The audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {VoiceBroadcast}
* @example
* // Play streams using ytdl-core
* const ytdl = require('ytdl-core');
* const streamOptions = { seek: 0, volume: 1 };
* const broadcast = client.createVoiceBroadcast();
*
* voiceChannel.join()
* .then(connection => {
* const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', { filter : 'audioonly' });
* broadcast.playStream(stream);
* const dispatcher = connection.playBroadcast(broadcast);
* })
* .catch(console.error);
*/
playStream(stream, options = {}) {
this.setVolume(options.volume || 1);
return this._playTranscodable(stream, options);
}
/**
* Play the given file in the voice connection.
* @param {string} file The absolute path to the file
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
* @example
* // Play files natively
* const broadcast = client.createVoiceBroadcast();
*
* voiceChannel.join()
* .then(connection => {
* broadcast.playFile('C:/Users/Discord/Desktop/music.mp3');
* const dispatcher = connection.playBroadcast(broadcast);
* })
* .catch(console.error);
*/
playFile(file, options = {}) {
this.setVolume(options.volume || 1);
return this._playTranscodable(`file:${file}`, options);
}
_playTranscodable(media, options) {
this.killCurrentTranscoder();
const transcoder = this.prism.transcode({
type: 'ffmpeg',
media,
ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek || 0)]),
});
/**
* Emitted whenever an error occurs.
* @event VoiceBroadcast#error
* @param {Error} error The error that occurred
*/
transcoder.once('error', e => {
if (this.listenerCount('error') > 0) this.emit('error', e);
delete(dispatcher) {
const index = this.subscribers.indexOf(dispatcher);
if (index !== -1) {
this.subscribers.splice(index, 1);
dispatcher.destroy();
/**
* Emitted whenever the VoiceBroadcast has any warnings.
* @event VoiceBroadcast#warn
* @param {string|Error} warning The warning that was raised
* Emitted whenever a stream dispatcher unsubscribes to the broadcast.
* @event VoiceBroadcast#unsubscribe
* @param {StreamDispatcher} dispatcher The unsubscribed dispatcher
*/
else this.emit('warn', e);
});
/**
* Emitted once the broadcast (the audio stream) ends.
* @event VoiceBroadcast#end
*/
transcoder.once('end', () => this.killCurrentTranscoder());
this.currentTranscoder = {
transcoder,
options,
};
transcoder.output.once('readable', () => this._startPlaying());
return this;
}
/**
* Plays a stream of 16-bit signed stereo PCM.
* @param {ReadableStream} stream The audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {VoiceBroadcast}
*/
playConvertedStream(stream, options = {}) {
this.killCurrentTranscoder();
this.setVolume(options.volume || 1);
this.currentTranscoder = { options: { stream } };
stream.once('readable', () => this._startPlaying());
return this;
}
/**
* Plays an Opus encoded stream.
* <warn>Note that inline volume is not compatible with this method.</warn>
* @param {ReadableStream} stream The Opus audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
*/
playOpusStream(stream) {
this.currentTranscoder = { options: { stream }, opus: true };
stream.once('readable', () => this._startPlaying());
return this;
}
/**
* Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description)
* @param {string} input The arbitrary input
* @param {StreamOptions} [options] Options for playing the stream
* @returns {VoiceBroadcast}
*/
playArbitraryInput(input, options = {}) {
this.setVolume(options.volume || 1);
options.input = input;
return this._playTranscodable(input, options);
}
/**
* Pauses the entire broadcast - all dispatchers also pause.
*/
pause() {
this.paused = true;
for (const container of this._dispatchers.values()) {
for (const dispatcher of container.values()) {
dispatcher.pause();
}
}
}
/**
* Resumes the entire broadcast - all dispatchers also resume.
*/
resume() {
this.paused = false;
for (const container of this._dispatchers.values()) {
for (const dispatcher of container.values()) {
dispatcher.resume();
}
}
}
_startPlaying() {
if (this.tickInterval) clearInterval(this.tickInterval);
// Old code?
// this.tickInterval = this.client.setInterval(this.tick.bind(this), 20);
this._startTime = Date.now();
this._count = 0;
this._pausedTime = 0;
this._missed = 0;
this.tick();
}
tick() {
if (!this._playableStream) return;
if (this.paused) {
this._pausedTime += 20;
setTimeout(() => this.tick(), 20);
return;
}
const opus = this.currentTranscoder.opus;
const buffer = this.readStreamBuffer();
if (!buffer) {
this._missed++;
if (this._missed < 5) {
this._pausedTime += 200;
setTimeout(() => this.tick(), 200);
} else {
this.killCurrentTranscoder();
}
return;
}
this._missed = 0;
let packetMatrix = {};
const getOpusPacket = volume => {
if (packetMatrix[volume]) return packetMatrix[volume];
const opusEncoder = this._encoders.get(volume);
const opusPacket = opusEncoder.encode(this.applyVolume(buffer, this._volume * volume));
packetMatrix[volume] = opusPacket;
return opusPacket;
};
for (const dispatcher of this.dispatchers) {
if (opus) {
dispatcher.processPacket(buffer);
continue;
}
const volume = dispatcher.volume;
dispatcher.processPacket(getOpusPacket(volume));
}
const next = 20 + (this._startTime + this._pausedTime + (this._count * 20) - Date.now());
this._count++;
setTimeout(() => this.tick(), next);
}
readStreamBuffer() {
const opus = this.currentTranscoder.opus;
const bufferLength = (opus ? 80 : 1920) * 2;
let buffer = this._playableStream.read(bufferLength);
if (opus) return buffer;
if (!buffer) return null;
if (buffer.length !== bufferLength) {
const newBuffer = Buffer.alloc(bufferLength).fill(0);
buffer.copy(newBuffer);
buffer = newBuffer;
}
return buffer;
}
/**
* Stop the current stream from playing without unsubscribing dispatchers.
*/
end() {
this.killCurrentTranscoder();
}
/**
* End the current broadcast, all subscribed dispatchers will also end.
*/
destroy() {
this.end();
for (const container of this._dispatchers.values()) {
for (const dispatcher of container.values()) {
dispatcher.destroy('end', 'broadcast ended');
}
this.emit(Events.VOICE_BROADCAST_UNSUBSCRIBE, dispatcher);
return true;
}
return false;
}
}
PlayInterface.applyToClass(VoiceBroadcast);
module.exports = VoiceBroadcast;

View File

@@ -1,11 +1,26 @@
const VoiceWebSocket = require('./VoiceWebSocket');
const VoiceUDP = require('./VoiceUDPClient');
const Util = require('../../util/Util');
const Constants = require('../../util/Constants');
'use strict';
const EventEmitter = require('events');
const VoiceUDP = require('./networking/VoiceUDPClient');
const VoiceWebSocket = require('./networking/VoiceWebSocket');
const AudioPlayer = require('./player/AudioPlayer');
const VoiceReceiver = require('./receiver/VoiceReceiver');
const EventEmitter = require('events').EventEmitter;
const Prism = require('prism-media');
const VoiceReceiver = require('./receiver/Receiver');
const PlayInterface = require('./util/PlayInterface');
const Silence = require('./util/Silence');
const { Error } = require('../../errors');
const { OPCodes, VoiceOPCodes, VoiceStatus, Events } = require('../../util/Constants');
const Speaking = require('../../util/Speaking');
const Util = require('../../util/Util');
// Workaround for Discord now requiring silence to be sent before being able to receive audio
class SingleSilence extends Silence {
_read() {
super._read();
this.push(null);
}
}
const SUPPORTED_MODES = ['xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305'];
/**
* Represents a connection to a guild's voice server.
@@ -17,6 +32,7 @@ const Prism = require('prism-media');
* });
* ```
* @extends {EventEmitter}
* @implements {PlayInterface}
*/
class VoiceConnection extends EventEmitter {
constructor(voiceManager, channel) {
@@ -28,23 +44,6 @@ class VoiceConnection extends EventEmitter {
*/
this.voiceManager = voiceManager;
/**
* The client that instantiated this connection
* @type {Client}
*/
this.client = voiceManager.client;
/**
* @external Prism
* @see {@link https://github.com/hydrabolt/prism-media}
*/
/**
* The audio transcoder for this connection
* @type {Prism}
*/
this.prism = new Prism();
/**
* The voice channel this connection is currently serving
* @type {VoiceChannel}
@@ -53,21 +52,15 @@ class VoiceConnection extends EventEmitter {
/**
* The current status of the voice connection
* @type {number}
* @type {VoiceStatus}
*/
this.status = Constants.VoiceStatus.AUTHENTICATING;
this.status = VoiceStatus.AUTHENTICATING;
/**
* Whether we're currently transmitting audio
* @type {boolean}
* Our current speaking state
* @type {Readonly<Speaking>}
*/
this.speaking = false;
/**
* An array of Voice Receivers that have been created for this connection
* @type {VoiceReceiver[]}
*/
this.receivers = [];
this.speaking = new Speaking().freeze();
/**
* The authentication data needed to connect to the voice server
@@ -100,13 +93,22 @@ class VoiceConnection extends EventEmitter {
this.emit('warn', e);
});
this.once('closing', () => this.player.destroy());
/**
* Map SSRC to speaking values
* @type {Map<number, boolean>}
* Map SSRC values to user IDs
* @type {Map<number, Snowflake>}
* @private
*/
this.ssrcMap = new Map();
/**
* Tracks which users are talking
* @type {Map<Snowflake, Readonly<Speaking>>}
* @private
*/
this._speaking = new Map();
/**
* Object that wraps contains the `ws` and `udp` sockets of this voice connection
* @type {Object}
@@ -114,7 +116,20 @@ class VoiceConnection extends EventEmitter {
*/
this.sockets = {};
this.authenticate();
/**
* The voice receiver of this connection
* @type {VoiceReceiver}
*/
this.receiver = new VoiceReceiver(this);
}
/**
* The client that instantiated this connection
* @type {Client}
* @readonly
*/
get client() {
return this.voiceManager.client;
}
/**
@@ -127,41 +142,61 @@ class VoiceConnection extends EventEmitter {
}
/**
* Sets whether the voice connection should display as "speaking" or not.
* @param {boolean} value Whether or not to speak
* @private
* Sets whether the voice connection should display as "speaking", "soundshare" or "none".
* @param {BitFieldResolvable} value The new speaking state
*/
setSpeaking(value) {
if (this.speaking === value) return;
if (this.status !== Constants.VoiceStatus.CONNECTED) return;
this.speaking = value;
this.sockets.ws.sendPacket({
op: Constants.VoiceOPCodes.SPEAKING,
d: {
speaking: true,
delay: 0,
},
}).catch(e => {
this.emit('debug', e);
});
if (this.speaking.equals(value)) return;
if (this.status !== VoiceStatus.CONNECTED) return;
this.speaking = new Speaking(value).freeze();
this.sockets.ws
.sendPacket({
op: VoiceOPCodes.SPEAKING,
d: {
speaking: this.speaking.bitfield,
delay: 0,
ssrc: this.authentication.ssrc,
},
})
.catch(e => {
this.emit('debug', e);
});
}
/**
* The voice state of this connection
* @type {?VoiceState}
*/
get voice() {
return this.channel.guild.voice;
}
/**
* Sends a request to the main gateway to join a voice channel.
* @param {Object} [options] The options to provide
* @returns {Promise<Shard>}
* @private
*/
sendVoiceStateUpdate(options = {}) {
options = Util.mergeDefault({
guild_id: this.channel.guild.id,
channel_id: this.channel.id,
self_mute: false,
self_deaf: false,
}, options);
options = Util.mergeDefault(
{
guild_id: this.channel.guild.id,
channel_id: this.channel.id,
self_mute: this.voice ? this.voice.selfMute : false,
self_deaf: this.voice ? this.voice.selfDeaf : false,
},
options,
);
this.client.ws.send({
op: Constants.OPCodes.VOICE_STATE_UPDATE,
d: options,
});
this.emit('debug', `Sending voice state update: ${JSON.stringify(options)}`);
return this.channel.guild.shard.send(
{
op: OPCodes.VOICE_STATE_UPDATE,
d: options,
},
true,
);
}
/**
@@ -169,26 +204,29 @@ class VoiceConnection extends EventEmitter {
* @param {string} token The voice token
* @param {string} endpoint The voice endpoint
* @returns {void}
* @private
*/
setTokenAndEndpoint(token, endpoint) {
this.emit('debug', `Token "${token}" and endpoint "${endpoint}"`);
if (!endpoint) {
// Signifies awaiting endpoint stage
return;
}
if (!token) {
this.authenticateFailed('Token not provided from voice server packet.');
this.authenticateFailed('VOICE_TOKEN_ABSENT');
return;
}
endpoint = endpoint.match(/([^:]*)/)[0];
this.emit('debug', `Endpoint resolved as ${endpoint}`);
if (!endpoint) {
this.authenticateFailed('Invalid endpoint received.');
this.authenticateFailed('VOICE_INVALID_ENDPOINT');
return;
}
if (this.status === Constants.VoiceStatus.AUTHENTICATING) {
if (this.status === VoiceStatus.AUTHENTICATING) {
this.authentication.token = token;
this.authentication.endpoint = endpoint;
this.checkAuthenticated();
@@ -200,14 +238,16 @@ class VoiceConnection extends EventEmitter {
/**
* Sets the Session ID for the connection.
* @param {string} sessionID The voice session ID
* @private
*/
setSessionID(sessionID) {
this.emit('debug', `Setting sessionID ${sessionID} (stored as "${this.authentication.sessionID}")`);
if (!sessionID) {
this.authenticateFailed('Session ID not supplied.');
this.authenticateFailed('VOICE_SESSION_ABSENT');
return;
}
if (this.status === Constants.VoiceStatus.AUTHENTICATING) {
if (this.status === VoiceStatus.AUTHENTICATING) {
this.authentication.sessionID = sessionID;
this.checkAuthenticated();
} else if (sessionID !== this.authentication.sessionID) {
@@ -227,10 +267,9 @@ class VoiceConnection extends EventEmitter {
*/
checkAuthenticated() {
const { token, endpoint, sessionID } = this.authentication;
this.emit('debug', `Authenticated with sessionID ${sessionID}`);
if (token && endpoint && sessionID) {
clearTimeout(this.connectTimeout);
this.status = Constants.VoiceStatus.CONNECTING;
this.status = VoiceStatus.CONNECTING;
/**
* Emitted when we successfully initiate a voice connection.
* @event VoiceConnection#authenticated
@@ -246,8 +285,9 @@ class VoiceConnection extends EventEmitter {
* @private
*/
authenticateFailed(reason) {
clearTimeout(this.connectTimeout);
if (this.status === Constants.VoiceStatus.AUTHENTICATING) {
this.client.clearTimeout(this.connectTimeout);
this.emit('debug', `Authenticate failed - ${reason}`);
if (this.status === VoiceStatus.AUTHENTICATING) {
/**
* Emitted when we fail to initiate a voice connection.
* @event VoiceConnection#failed
@@ -255,9 +295,14 @@ class VoiceConnection extends EventEmitter {
*/
this.emit('failed', new Error(reason));
} else {
/**
* Emitted whenever the connection encounters an error.
* @event VoiceConnection#error
* @param {Error} error The encountered error
*/
this.emit('error', new Error(reason));
}
this.status = Constants.VoiceStatus.DISCONNECTED;
this.status = VoiceStatus.DISCONNECTED;
}
/**
@@ -276,8 +321,7 @@ class VoiceConnection extends EventEmitter {
*/
authenticate() {
this.sendVoiceStateUpdate();
this.connectTimeout = this.client.setTimeout(
() => this.authenticateFailed(new Error('Connection not established within 15 seconds.')), 15000);
this.connectTimeout = this.client.setTimeout(() => this.authenticateFailed('VOICE_CONNECTION_TIMEOUT'), 15000);
}
/**
@@ -289,8 +333,9 @@ class VoiceConnection extends EventEmitter {
reconnect(token, endpoint) {
this.authentication.token = token;
this.authentication.endpoint = endpoint;
this.status = Constants.VoiceStatus.RECONNECTING;
this.speaking = new Speaking().freeze();
this.status = VoiceStatus.RECONNECTING;
this.emit('debug', `Reconnecting to ${endpoint}`);
/**
* Emitted when the voice connection is reconnecting (typically after a region change).
* @event VoiceConnection#reconnecting
@@ -300,16 +345,27 @@ class VoiceConnection extends EventEmitter {
}
/**
* Disconnect the voice connection, causing a disconnect and closing event to be emitted.
* Disconnects the voice connection, causing a disconnect and closing event to be emitted.
*/
disconnect() {
this.emit('closing');
this.emit('debug', 'disconnect() triggered');
this.client.clearTimeout(this.connectTimeout);
const conn = this.voiceManager.connections.get(this.channel.guild.id);
if (conn === this) this.voiceManager.connections.delete(this.channel.guild.id);
this.sendVoiceStateUpdate({
channel_id: null,
});
this.player.destroy();
this._disconnect();
}
/**
* Internally disconnects (doesn't send disconnect packet).
* @private
*/
_disconnect() {
this.cleanup();
this.status = Constants.VoiceStatus.DISCONNECTED;
this.status = VoiceStatus.DISCONNECTED;
/**
* Emitted when the voice connection disconnects.
* @event VoiceConnection#disconnect
@@ -322,13 +378,18 @@ class VoiceConnection extends EventEmitter {
* @private
*/
cleanup() {
this.player.destroy();
this.speaking = new Speaking().freeze();
const { ws, udp } = this.sockets;
this.emit('debug', 'Connection clean up');
if (ws) {
ws.removeAllListeners('error');
ws.removeAllListeners('ready');
ws.removeAllListeners('sessionDescription');
ws.removeAllListeners('speaking');
ws.shutdown();
}
if (udp) udp.removeAllListeners('error');
@@ -342,9 +403,10 @@ class VoiceConnection extends EventEmitter {
* @private
*/
connect() {
if (this.status !== Constants.VoiceStatus.RECONNECTING) {
if (this.sockets.ws) throw new Error('There is already an existing WebSocket connection.');
if (this.sockets.udp) throw new Error('There is already an existing UDP connection.');
this.emit('debug', `Connect triggered`);
if (this.status !== VoiceStatus.RECONNECTING) {
if (this.sockets.ws) throw new Error('WS_CONNECTION_EXISTS');
if (this.sockets.udp) throw new Error('UDP_CONNECTION_EXISTS');
}
if (this.sockets.ws) this.sockets.ws.shutdown();
@@ -355,11 +417,15 @@ class VoiceConnection extends EventEmitter {
const { ws, udp } = this.sockets;
ws.on('debug', msg => this.emit('debug', msg));
udp.on('debug', msg => this.emit('debug', msg));
ws.on('error', err => this.emit('error', err));
udp.on('error', err => this.emit('error', err));
ws.on('ready', this.onReady.bind(this));
ws.on('sessionDescription', this.onSessionDescription.bind(this));
ws.on('speaking', this.onSpeaking.bind(this));
ws.on('startSpeaking', this.onStartSpeaking.bind(this));
this.sockets.ws.connect();
}
/**
@@ -367,39 +433,51 @@ class VoiceConnection extends EventEmitter {
* @param {Object} data The received data
* @private
*/
onReady({ port, ssrc }) {
this.authentication.port = port;
this.authentication.ssrc = ssrc;
const udp = this.sockets.udp;
/**
* Emitted whenever the connection encounters an error.
* @event VoiceConnection#error
* @param {Error} error The encountered error
*/
udp.findEndpointAddress()
.then(address => {
udp.createUDPSocket(address);
}, e => this.emit('error', e));
onReady(data) {
Object.assign(this.authentication, data);
for (let mode of data.modes) {
if (SUPPORTED_MODES.includes(mode)) {
this.authentication.mode = mode;
this.emit('debug', `Selecting the ${mode} mode`);
break;
}
}
this.sockets.udp.createUDPSocket(data.ip);
}
/**
* Invoked when a session description is received.
* @param {string} mode The encryption mode
* @param {string} secret The secret key
* @param {Object} data The received data
* @private
*/
onSessionDescription(mode, secret) {
this.authentication.encryptionMode = mode;
this.authentication.secretKey = secret;
onSessionDescription(data) {
Object.assign(this.authentication, data);
this.status = VoiceStatus.CONNECTED;
const ready = () => {
this.client.clearTimeout(this.connectTimeout);
this.emit('debug', `Ready with authentication details: ${JSON.stringify(this.authentication)}`);
/**
* Emitted once the connection is ready, when a promise to join a voice channel resolves,
* the connection will already be ready.
* @event VoiceConnection#ready
*/
this.emit('ready');
};
if (this.dispatcher) {
ready();
} else {
// This serves to provide support for voice receive, sending audio is required to receive it.
const dispatcher = this.play(new SingleSilence(), { type: 'opus', volume: false });
dispatcher.once('finish', ready);
}
}
this.status = Constants.VoiceStatus.CONNECTED;
/**
* Emitted once the connection is ready, when a promise to join a voice channel resolves,
* the connection will already be ready.
* @event VoiceConnection#ready
*/
this.emit('ready');
onStartSpeaking({ user_id, ssrc, speaking }) {
this.ssrcMap.set(+ssrc, {
...(this.ssrcMap.get(+ssrc) || {}),
userID: user_id,
speaking: speaking,
});
}
/**
@@ -407,129 +485,42 @@ class VoiceConnection extends EventEmitter {
* @param {Object} data The received data
* @private
*/
onSpeaking({ user_id, ssrc, speaking }) {
onSpeaking({ user_id, speaking }) {
speaking = new Speaking(speaking).freeze();
const guild = this.channel.guild;
const user = this.client.users.get(user_id);
this.ssrcMap.set(+ssrc, user);
if (!speaking) {
for (const receiver of this.receivers) {
receiver.stoppedSpeaking(user);
const user = this.client.users.cache.get(user_id);
const old = this._speaking.get(user_id);
this._speaking.set(user_id, speaking);
/**
* Emitted whenever a user changes speaking state.
* @event VoiceConnection#speaking
* @param {User} user The user that has changed speaking state
* @param {Readonly<Speaking>} speaking The speaking state of the user
*/
if (this.status === VoiceStatus.CONNECTED) {
this.emit('speaking', user, speaking);
if (!speaking.has(Speaking.FLAGS.SPEAKING)) {
this.receiver.packets._stoppedSpeaking(user_id);
}
}
if (guild && user && !speaking.equals(old)) {
const member = guild.member(user);
if (member) {
/**
* Emitted once a guild member changes speaking state.
* @event Client#guildMemberSpeaking
* @param {GuildMember} member The member that started/stopped speaking
* @param {Readonly<Speaking>} speaking The speaking state of the member
*/
this.client.emit(Events.GUILD_MEMBER_SPEAKING, member, speaking);
}
}
/**
* Emitted whenever a user starts/stops speaking.
* @event VoiceConnection#speaking
* @param {User} user The user that has started/stopped speaking
* @param {boolean} speaking Whether or not the user is speaking
*/
if (this.status === Constants.VoiceStatus.CONNECTED) this.emit('speaking', user, speaking);
guild._memberSpeakUpdate(user_id, speaking);
}
/**
* Options that can be passed to stream-playing methods:
* @typedef {Object} StreamOptions
* @property {number} [seek=0] The time to seek to
* @property {number} [volume=1] The volume to play at
* @property {number} [passes=1] How many times to send the voice packet to reduce packet loss
* @property {number|string} [bitrate=48000] The bitrate (quality) of the audio.
* If set to 'auto', the voice channel's bitrate will be used
*/
/**
* Play the given file in the voice connection.
* @param {string} file The absolute path to the file
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
* @example
* // Play files natively
* voiceChannel.join()
* .then(connection => {
* const dispatcher = connection.playFile('C:/Users/Discord/Desktop/music.mp3');
* })
* .catch(console.error);
*/
playFile(file, options) {
return this.player.playUnknownStream(`file:${file}`, options);
}
/**
* Play an arbitrary input that can be [handled by ffmpeg](https://ffmpeg.org/ffmpeg-protocols.html#Description)
* @param {string} input the arbitrary input
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
*/
playArbitraryInput(input, options) {
return this.player.playUnknownStream(input, options);
}
/**
* Plays and converts an audio stream in the voice connection.
* @param {ReadableStream} stream The audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
* @example
* // Play streams using ytdl-core
* const ytdl = require('ytdl-core');
* const streamOptions = { seek: 0, volume: 1 };
* voiceChannel.join()
* .then(connection => {
* const stream = ytdl('https://www.youtube.com/watch?v=XAWgeLF9EVQ', { filter : 'audioonly' });
* const dispatcher = connection.playStream(stream, streamOptions);
* })
* .catch(console.error);
*/
playStream(stream, options) {
return this.player.playUnknownStream(stream, options);
}
/**
* Plays a stream of 16-bit signed stereo PCM.
* @param {ReadableStream} stream The audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
*/
playConvertedStream(stream, options) {
return this.player.playPCMStream(stream, options);
}
/**
* Plays an Opus encoded stream.
* <warn>Note that inline volume is not compatible with this method.</warn>
* @param {ReadableStream} stream The Opus audio stream to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
*/
playOpusStream(stream, options) {
return this.player.playOpusStream(stream, options);
}
/**
* Plays a voice broadcast.
* @param {VoiceBroadcast} broadcast The broadcast to play
* @param {StreamOptions} [options] Options for playing the stream
* @returns {StreamDispatcher}
* @example
* // Play a broadcast
* const broadcast = client
* .createVoiceBroadcast()
* .playFile('./test.mp3');
* const dispatcher = voiceConnection.playBroadcast(broadcast);
*/
playBroadcast(broadcast, options) {
return this.player.playBroadcast(broadcast, options);
}
/**
* Creates a VoiceReceiver so you can start listening to voice data.
* It's recommended to only create one of these.
* @returns {VoiceReceiver}
*/
createReceiver() {
const receiver = new VoiceReceiver(this);
this.receivers.push(receiver);
return receiver;
}
play() {} // eslint-disable-line no-empty-function
}
PlayInterface.applyToClass(VoiceConnection);
module.exports = VoiceConnection;

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