#archive-library-discussion

1 messages · Page 1 of 1 (latest)

merry python
#

this channel is for serious discussions only

#

please refrain from memes

rigid trail
#

alright, lets christen the channel by bringing up an issue with websocket event handlers, the gist of it is there is no distinction between handlers and actions, some handlers just call actions, some call actions and have their own logic, etc. the full issue is right here https://github.com/discordjs/discord.js/issues/3790, my question is how would you implement a solution, considering some actions are also called internally by the lib too. (This will be a v13 thing).

fringe temple
#

This channel is specifically for discussions about the development of the library Discord.js. That means you can't ask for help using Discord.js in this channel, and talking about moderation/server administration isn't appropriate here either. Talking about issues/pull requests or features is appropriate, however!

vernal atlas
#

also on that, should the finish listener be .once instead of .on?

slate nacelle
#

I'd say yes to both

undone ravine
#

i'd say no to once instead of on

#

finish is an event from WritableStream, and typically does indicate that there will never be any more data written to it... at which point the object is essentially being disposed of anyways

#

and if somebody somehow manages to kludge in a way to reuse the stream after that, we'd still want it to do the same stuff on finish

#

not at all a valid use-case, but the listener is going away with the object anyways

vernal atlas
#

hmm, ok

#

also, https://github.com/discordjs/discord.js/blob/9cb306c823216130e5bddc268ba3aee025a5b98f/src/client/voice/dispatcher/StreamDispatcher.js#L235 here done seems to be called without actually checking if it is a function or not (possibly resulting in an error as done won't be a function), if you look https://github.com/discordjs/discord.js/blob/9cb306c823216130e5bddc268ba3aee025a5b98f/src/client/voice/dispatcher/BroadcastDispatcher.js#L19 here you can see the method is called without a 3rd parameter, i'm not sure how the writable streams and whatnot work, so i'm not sure exactly how to fix it, i thought id point this out incase anyone wants to fix it

#

ill open an issue about it later

spice lava
#

I am extremly unsure about the possibility and if this is something the devs would support, but it would be an idea to actually use the typings for typescript users in terms of enums. So I personally as an example just cant remember the zws code so one possibility would be to have Sign.ZWS or similar within typescript enums.
Whats do you think

copper laurel
#

v13 is highly likely to at least partially be a TS rewrite, probably fully, so stuff like that can be considered. The ZWS isn't really discord functionality though, so in terms of it being part of the library core that's a bit questionable. At the very least I'd say it could be a snippet in the guide like the emoji numbers workaround.

#

Something people can easily implement in their own code as a util

zenith monolith
#

Will there be a streamEnd reason in v12 or is there already that im not aware of?

warped crater
#

Hello, considering that this channel now exists it seems pointless to ask this in #archive-offtopic and expect a quick response I will go on ahead with my thing

I am totally confused about the disableEveryone -> disableMentions change, why exactly was this done.

I totally understand the purpose of disableMentions, but I think a very large portion of us only want to disable <@&265426791538229258> & <@&265427044882579456> to completely nullify any possible oopsies.
Should also be noted that disabling ALL mentions for us is inane and is not something we can easily do.

vernal atlas
#

https://github.com/discordjs/discord.js/blob/9cb306c823216130e5bddc268ba3aee025a5b98f/src/client/voice/networking/VoiceWebSocket.js#L4 so apperently you don't have to use the EventEmitter property from the events module (bad wording but, you can do const EventEmitter = require("events") instead of const { EventEmitter } = require("events"), should i change this throughout the lib to use the first way or the second, as both ways seem to be used throughout (im doing a PR to fix little things like this)

wild flax
#

No, we had a PR changing it to be the destructured one

#

The former is just a global namespace

vernal atlas
#

aight, so ill make everything use the destructured?

wild flax
#

Its not entirely consistent, but it doesnt have to be

#

But I guess

#

its a non-trivial change

#

Actually

#

It should be consistent already

vernal atlas
#

in some places it does const EventEmitter = ... and some places const { EventEmitter } = ...

#

so not consistent it seems?

fringe temple
#

In response to streamEnd, no there will not, you should use the debug event to listen for related info instead

vernal atlas
#

in some files, the EventEmitter.off method is used over EventEmitter.removeListener (which they are the exact same method it seems), for consistency, which one would be better?

#

pretty small change i know thinkLul, just doing a PR to improve consistency in certian places and figured i may as well include everything

frozen current
#

Djs uses on to add listeners so I guess off to remove them would make sense. My personal opinions is addListener and removeListener would look better as it’s more descriptive if you wanna go around and change everything mmLol

#

@vernal atlas

vernal atlas
#

hm

rigid trail
#

I disagree, in the end its a lot of refactoring for really an extremely minor change, and chances are, if you are looking at source code you already know what .on and .off do

vernal atlas
#

yea

copper laurel
#

imo looking at the websocket event handlers and actions, there's definitely cleanup potential. There may still be a need to differentiate between handling when the event is from a websocket, and handling when its a lib call/rest related, but that can easily be done by a single class that has different methods. No need to separate the two

rigid trail
#

imo a class with one or more methods sounds good

#

although there might be a way to just merge into one method and if possible have something resolve if its a raw packet or not

#

@copper laurel ^

copper laurel
#

Maybe, but I don't think that improves maintability over separate methods

real jetty
#

ive been working on local changes ages ago for rewriting the logic for actions, i pushed 2 days ago to clean my working tree for rebasing some other pr. so here's some of my insight about this..
u can easily distinguish between whether the rest called the handler or whether it was the ws itself via a simple param (https://github.com/izexi/discord.js/blob/packet-handler/src/client/websocket/handlers/index.js#L42 3rd param is set to true over on WebSocketManager#handlePacket()). the actual issue is with handling overlap from the ws & rest, theres 2 ways to get around this: either don't call the handler at all for rest calls and return a patched structure or call the handler and add some logic within the handler to ensure the same function doesn't get run twice which in most cases turns out in unexpected behavior (which is pretty much for the *_CREATE/UPDATE/DELETE events - https://github.com/izexi/discord.js/blob/packet-handler/src/client/websocket/handlers/index.js#L4-L18). the 1st solution is somewhat hacky and is currently used in some places atm (e.g: when GuildChannel#delete() is called it returns the channel itself which isn't always guaranteed to be .deleted or removed from the ChannelStore) so i went with the 2nd and simply just stored the structure that has been "handled" and then return that when the handler gets called again from ws/rest (note that the order isn't always consistent) similarly to how its currently done on the current GuildDelete action.
another major concern is the stability of all this, hence y i started off by setting out some tests for all this https://github.com/izexi/discord.js/blob/packet-handler/test/packetHandler.test.js
im planning to allow more flexibility for the PacketHandler class so that it can be interacted with externally allowing developers to inject their own handlers, so thats a todo along with some cleanup which i will prolly finish after my exams

vernal atlas
#

im assuming it must have passed that check when that change was merged, so what's changed there

#

looking at git blame, it seems it didn't pass the checks (its quite old so its not available anymore to see exactly whats wrong) but shouldn't it have fired off errors in other PRs in that file?

worthy coral
#

Was looking at commits to upgrade my client to and I noticed that as of 9cb306c8, disableEveryone was replaced with disableMentions.
https://github.com/discordjs/discord.js/blob/653784b56445b015a1584de1b693e57fc9069050/src/structures/APIMessage.js#L95
For some clients, this functionality might be intended and helpful and I understand that this fixes exploitation of clients using the disableEveryone option but still being able to mention everyone and here via RTL override char but completely replacing all at symbols which might contain mentions to users and the developer having the intent to mention a user but not be able to mention everyone and here is very limiting. I do, however, like the idea of it being a client option.
I do have a proposed solution to make the two work in tandem which would be to either reintroduce the option itself or change ClientOptions#disableMentions to be of type "all" | "everyone"

vernal atlas
#

that sounds alright, but it can't have the same implentation as before

#

as you would have to find every character discord strips and strip it

#

the whole reason of disableMentions was because disableEveryone (or as you proposed above, disableMentions set to "everyone") was unreliable

worthy coral
#

Like I said, I’m aware it fixes the RTLO char issue but if someone were to reimplement it, they could just strip the RTLO char after at symbols

vernal atlas
#

yeah but its not only that character

#

from what i gather, there are quite a few characters that discord strip from the messge which aren't all documented

#

making it unreliable

worthy coral
#

The way the current implementation does it is by adding a ZWSP after all at symbols which does work so that implementation would be a viable fix

vernal atlas
#

yeah exactly

worthy coral
#

I see where you’re getting at now. Regular expressions

vernal atlas
#

$>js const regex = /@.+(everyone)/; const text = "@vernal atlas say hello to everyone"; text.replace(regex, "@\u200b$1");

pearl glacierBOT
#
<@​everyone

vernal atlas
#

needs a bit of work kappapuff

#

maybe test a regex on a string like that first

wild flax
#

Yeah I have no intentions of accepting something that’s only working 50 percent of the time

#

Neither am I okay with adding a disclaimer like “this only works as long as someone doesn’t want to fuck you over” lol

worthy coral
#

Working on it

worthy coral
#

Ended up making it more reliable and be future proof if any other unicode characters are discovered to become a vulnerability

Relative regular expression if you want to test it. If anything breaks the intended functionality, let me know

/@([^<> ]*?(?:everyone|here))/g

Below are tests of both methods which I modified the source to allow either method to be run.
Below the output is how the client would look like when it's constructed and also an image of the test source
https://cdn.discordapp.com/attachments/682818889993814078/682851488552321070/unknown.png
https://cdn.discordapp.com/attachments/682818889993814078/682851620488478721/unknown.png
https://cdn.discordapp.com/attachments/682818889993814078/682851723756568618/unknown.png
https://cdn.discordapp.com/attachments/682818889993814078/682851784099758101/unknown.png
https://cdn.discordapp.com/attachments/682818889993814078/682852007744110614/unknown.png

#

Yikes. My client appears to be broken rendering the embedded images

#

The "all" disableMentions uses the method in the latest commit

#

@vernal atlas @wild flax if you two were curious ^

grave pollen
#

disableMentions: "false",?

worthy coral
#

?

wild flax
#

Is this including the test cases of the original PR?

worthy coral
#

No. I can test those as well really quickly

#

Test 2 failed. I'll look for a fix

worthy coral
#

Ended up having to change the regular expression to

/@([^<>@ ]*?(?:everyone|here))/gsmu

And all of the tests passed. Both disabling everyone/here and all mentions ended up producing the exact same output

worthy coral
#

While all of the tests did pass, I found another issue which was to put the RTLO anywhere inside of the everyone or here which I am going to look for a fix now

ornate topaz
#

at this point i'm going to again suggest doing this from the other side

#

instead of assuming every string is safe and try to search for word everyone in it to put zws, treat every @ character as unsafe unless you can use it to form a valid user mention

#

makes it a bit easier, as user/role mentions cannot have letters, so pretty much any try to make everyone ping disguised as user mention will fail, as basic /<@!?\d{17,19}>/ already fails

wild flax
#

how does that play out with the guild id

#

just an additional check?

ornate topaz
#

is it possioble to mention everyone role with guild id?

wild flax
#

I mean that is the everyone role

#

the guild id

ornate topaz
#

if it is possibel to perform actual everyone ping using guild id and role mention, probably check would be needed

#

if it doesn't work as actual everyone ping, there is no point in checking for guild id being used

wild flax
#

ah its actually producing @@everyone

#

strange

#

well why dont you just PR it then

#

here it will just get lost

#

if you have a working implementation

ornate topaz
#

okay, gonna sit at it in an hour or so

worthy coral
#

I believe I got a good enough implementation, now

vernal atlas
#

i don't think that actually mentions people tho

ornate topaz
#

looking into source code (and on screenshots) it should

#

it doesn't put zws if this regex matches, at least that's what i get from the PR

worthy coral
#

I think they were referring to @<@&265426791538229258>

wild flax
#

yeah it doesnt work

#

normal, escaped, role, user (guildid), user (guildid)

warped crater
#

tried the escape too yesterday when I was tryna find a workaround

#

I ended up just underlining the @, its subtle; not ideal but it does what I need it to

vernal atlas
wild flax
#

that jump link somehow does not work for me

frozen current
vernal atlas
#

interesting

vernal atlas
spice lava
#

Yeah seems actually smart to do that

snow crypt
#

What if Message#awaitReactions and TextBasedChannel#awaitMessages moved to the managers?
Like message.reactions.await and channel.messages.await

#

same for collectors, message.reactions.createCollector

rigid trail
#

Personally i dont believe that naming it .await is a good naming scheme

#

You also run into the issue that its not for the purpose of a manager

#

await.. does not make api calls, therefore its out of the scope of the manager

snow crypt
#

maybe it should be?

rigid trail
#

That would completely bork the purpose of a manager

snow crypt
#

yes, the purpose of managers (originally) was to separate api from cache

rigid trail
#

And it still will be

#

The whole purpose of a manager is to be able to distinguish what uses the api

#

If you start adding these things it completely clouds the purpose of it

snow crypt
#

i dont know, kinda makes sense for everything reaction or message to be in one place

#

for the same reason datastores were originally introduced

burnt cradle
#

And the same reason stores were removed

rigid trail
#

exactly

#

Honestly, if things like these are allowed to be implemented, managers will become the same crapshoot that datastores where ¯_(ツ)_/¯

#

plus think about it, does it interact at all with the cache of messages? Nope, does it interact with the api to do something to the cache? Nope

vernal atlas
#

yeah i agree it should stay as is

vernal atlas
#

and also, wouldn't [K in keyof Omit<T, 'id' | 'partial'>]: T[K] | null; mark things such ascreatedAt as possibly being null, when infact they can't

zenith monolith
#

Will there be a dispatcher end reason in master?

snow crypt
#

What is reply-prefix for? Also, if it is needed in the main lib, why isn't it merged into master?

ornate topaz
analog oyster
umbral aspen
#

What do you mean? That looks fine

analog oyster
#

'none' vs none'

#

just noticed I came to the wrong channel

ornate root
#

since only userbots update a note

ornate topaz
#

none of 3 user-account-only events have a note about deprecation, my guess is that there is nothing emitted for them if you have bot account. emitting them doesn't make much sense either.
additionally, all are removed on master, along with all user-account-only methods

slate nacelle
#

I think it's too late for that now

snow crypt
#

not sure the docgen will do something about @depracated on @events

vernal atlas
#

i seem to be having an issue with the VoiceChannel.join (ClientVoiceManager.joinChannel) not resolving, can anyone else reproduce?

#

can't recall exactly what commit im using, but i updated a couple nights ago and i don't think there has been any changes to the voice since then

wild flax
#

thats an ever lasting problem

ornate topaz
#

(there was one literally minutes ago)

wild flax
#

and the one minutes ago yeah

vernal atlas
#

ah

real jetty
#

Question about 11.6.0, why would bots be able to recieve urgent system messages?

#

According to the help article (https://support.discordapp.com/hc/en-us/articles/360036118732-Discord-System-Messages), the only reasons why an urgent message would be sent is for user-related issues such as payment problems, support ticket updates, and ToS violations

#

Also, why are message flags applicable to Message#edit?

#

Another question, GuildMember#manageable seems poorly documented. I dont understand what would constitute a member being "manageable"
maybe an example would help

unique axle
#

for that last one: i think that message is pretty clear if you know how discord works
role hierarchy dictates if you are able to action a member - be that nickname them, kick/ban them etc.
if the highest role of the target (instance this is called on) is higher or equal than the logged in users (bots) highest role they are not actionable/manageable

real jetty
#

So, manageable then becomes a shortcut for
targetMember.highestRole.position > message.guild.me.highestRole.position

undone ravine
#

and an owner check

unique axle
#

Also, why are message flags applicable to Message#edit?
do you mean not applicable to Message#edit?
flags are not applied via a patch request, that Message#edit constitutes

undone ravine
#

i do agree that the description for manageable could be improved

unique axle
#

any suggestion then?

undone ravine
#

we shouldn't make the assumption that users of the lib are 100% familiar with the ins and outs of discord

unique axle
#

you don't really need to be with the description as-is, it really is just that, manageable in terms of role hierarchy
what exactly that is can be as much of a blackbox as you want imho

real jetty
#

No, @unique axle I mean applicable.
If you follow the documentation from Message#edit, it accepts two parameters: content, and MessageEditOptions.
MessageEditOptions includes the ability to set flags

undone ravine
#

probably just an addition to it elaborating on what "manageable" means

real jetty
#

This is why I'm confused, one would think that's read only. And even if, n/a

unique axle
real jetty
#

Ok, so then, why include all of the flags when it seems that only embed suppression can be applied?

#

To account for those that use bitwise operators? Or bitfields? or..

unique axle
#

why provide that interface at all, when on master it isn't public facing and you can just call Message#suppress... anyways
is the question i'm having now, probably an oversight potatodetective

real jetty
#

Interesting.
Seems then it's been "fixed" in master, so I wont bother with this any longer

unique axle
#

So in summary:
Q: Why is urgent system message in MessageFlags
A: It's documented in the public API documentation https://discordapp.com/developers/docs/resources/channel#message-object-message-flags
WIth discord.js trying to be API complete it should be compatible with it.

Q: GuildMember#manageable is unclear
A: Thanks for the suggestion, you can track its status here: https://github.com/discordjs/discord.js/pull/3870

Q: Flags being part of Message#edit despite their informational nature:
A: V12 removes this behavior and just allows Message#suppressEmbeds to be called without direct ability to pass flags into Message#edit

clever crypt
#

I wanted to go about editing all appropriate tags for the release of v12 but I'm semi-confused by which version is which. Additionally, I don't have permissions to edit tags which aren't mine. So below is a list of all tags that need changing.

documentation,~~ stable~~, master, 11.5-dev

feel free to ping me in #archive-offtopic if more need to be added

edit: thanks space!

slate nacelle
#

Should be updated (or deleted in case of 11.5-dev) blobthumbsup

tawny warren
#

other than the cache and addBlankField are there any major changes in v12 if i was already using it before now?

clever crypt
wide palm
#

The v12 update announcement said that node needed to be updated to v12, but the update guide has said (up til and including now) that node would need to be updated to v10.2
Which is correct?

rigid trail
#

v12 is correct, guide will be updated

wide palm
#

Ok, thank you!

white grove
#

Is there any big reason to upgrade to djs v12 if you don't specifically need any of the new features?

warped crater
#

yes

#

v11 is going to become deprecated & eventually EOL

#

unless its a huge hassle you should rewrite when you can yeptune

white grove
#

Was afraid of that, thanks

spice lava
#

to be fair the rewrite is not as big as I thought too. I changed not listening to raw event now and using partials and just changing shit around to use caches etc. Took me less than 2 hours for the whole project (which included unit test adjustment)

zinc folio
#

yeah, the effort to rewrite code with this update was thankfully minimal and painless, thanks djsdevs 👍

opaque vessel
#

This may be some sort of minor feature request, but can .displayAvatarURL() use .png as a default instead of .webp? On iOS, we can't see it because apparently Discord doesn't support it? I have to specify that option every time as well as take into consideration animated profile pictures because of it for iOS users

small flame
#

you can do that with the dynamic property

#

you set a default format with the format option and then set dynamic to true so it defaults to gifs for animated one's

#

but for the library i would rather tend to say no since that brings opinions into it, you can ofc create an default
options object and reuse that through your application, which i would recommend

opaque vessel
#

I don't understand what you mean, the first half is what I am already doing because of it but right now discord.js defaults to using .webp?

small flame
#

yes and as i said you should continue doing that and d.js should not change it default behavior because of an bug on ios since thats opinionated

rigid trail
#

I disagree with the point of “that brings opinions into it”, while its true, the opinion of most people is png is generally favored over webp, so this would be a nice QOL change

opaque vessel
#

It's not a bug, it's just unsupported

small flame
#

the opinion of most people is png is generally favored over webp this is not at all true, you should not assume what people think imo

wild flax
#

iOS supports webP just fine, its discord on iOS

opaque vessel
#

Yeah, that

small flame
#

it is a bug with discord

#

which djs shouldn't monkey patch imo

opaque vessel
#

But the problem is that if this was to truly work for everyone, for now it would be better using .png? Cause everywhere in my code I always have to specify those options

small flame
#

you can write an getter which sets the default options, you can extend the structure for that

wild flax
#

We can't just change it back and forth all the time

#

So for now is a bad metric

opaque vessel
#

I don't see why you'd need to change it back

wild flax
#

Tinier filesize, less bandwidth

opaque vessel
#

Oh I see... well thank you for replying everyone

small flame
#

i dont see why d.js would need to change it in the first place when you clearly can just make your own options and extend the Structure with a custom method to use your own "default" options Eyes

opaque vessel
#

Sounds unnecessary

wild flax
#

Thats an opinion

small flame
#

well it might be unnecessary but it solves your problem you mentioned Cause everywhere in my code I always have to specify those options

#

with a custom method which uses these options you dont anymore

zealous parrot
#

Why did you guys have to break discord.js like that

#

Like bruh

rigid trail
#

offtopic

zealous parrot
#

How

rigid trail
#

this is about serious discussion, not just "wtf bruh"

#

if you want to discuss it seriously bring up serious points about why its bad

zealous parrot
#

Yes discord.js is broke, that is my response. It just doesn’t work, I’ve heard many people say that the devs changed the way that data is stored

#

And it caused it to not work

rigid trail
#

yep, managers

#

per semver, 11 => 12 breaks code

opal mauve
#

there's an extensive article on the official guide about migrating. if you're frustrated with the changes, I suggest you take a look

real jetty
#

@rigid trail, that's why I already use master version

tired kindle
#

I think when you major version it's intended to specify the library naming or functionality changed in a backwards incompatible way

snow crypt
#

literally impossible in this case

#

managers, fine - just add collection methods that call the ones on their cache

#

but url functions like iconURL would be impossible because it would have to be callable AND a string

#

but not ideal

#

and really, just replace anything that ends with URL with ....URL()

#

anyway, i migrated to master from stable when v12 was master, and it was not that difficult

#

wow

unique axle
#

pinmorning Regarding breaking changes in version 12 and updating:

  • We have an extensive guide on updating at https://discordjs.guide/additional-info/changes-in-v12.html?v=12
  • Alternatively you can revert the update by changing the entry in your package.json to ^11.6.1 (the last version of v11) and running npm update discord.js
  • Or un- and re-install it with npm rm discord.js, npm i discord.js@11.6.1

Note: Major versions are prone to breaking changes as per semver: https://semver.org/#spec-item-8
Note: The ^ here signifies "compatible with" https://docs.npmjs.com/files/package.json and prevents breaking updates from being applied accidentally

small flame
#

@unique axle do me a favor and pin that

vagrant holly
small flame
#

i would say d.js should not validate the fields when receiving at all should it?

#

i dont really see a reason since it comes from discord AreYouSweating

vagrant holly
#

Right, makes sense. MessageEmbed is also what's used by library users to make embeds though, right?
So I guess a flag would need to be added to the constructor to indicate it should skip validation?

small flame
#

yea i think so, discord might do stuff which breaks d.js internal checks at any time so i dont think checking against received embeds makes much sense,

#

i guess a flag would work

vagrant holly
#

What's super annoying is I can't reproduce this locally

small flame
#

hmm?

vagrant holly
#

Posting that link with a test bot on 12.0.1 doesn't seem to crash it

small flame
#

oh

#

wait can you check the embed type for me

#

is it rich or link

vagrant holly
#

What's the best way to check that

small flame
#

just check the embed type in the embed of the message you receive

vagrant holly
#

article

small flame
#

oh?

vagrant holly
#

Yup

small flame
#

the embed you logged had the type rich tho

vagrant holly
#

Indeed it does

small flame
#

thats interresting

snow crypt
#

it is rich

#

i pointed out in genral

vagrant holly
#

I've no idea where the message is, somewhere in one of the 4k servers the bot that's crashing is

small flame
#

yea but we should still not validate fields when receiving

vagrant holly
#

Yeah, I'm about to raise the PR for that

small flame
#

since as you just saw it might have different specs

#

yes 👍

vagrant holly
#

Just can't confirm it's actually fixed that issue

small flame
#

well

#

it should since that error comes from d.js field checking

heavy dove
#

Anyone using vscode getting errors after installing v12

small flame
#

vscode has nothing to do with the library

vernal atlas
slate nacelle
#

I'd say so, yes.

vernal atlas
#

what would be a better description for it? having trouble coming up with one

vagrant holly
#

The date displayed on the embed

#

?

slate nacelle
#

Something like that, maybe?

Now that I see it, the name createdAt seems to be a bit of a misnomer. too.
Just date would probably have been better, but it's too late for that now.

vernal atlas
#

yea

#

Just date would probably have been better, but it's too late for that now.

should i make a PR to just change the description then?

slate nacelle
#

Yep

vagrant holly
#

@slate nacelle You're SpaceEEC on GH, right?

#

So, we're removing the whole docstrings for constructor & setup due to skipValidation being a private param

#

However, normalizeField and _normalizeFields also have that param

#

But we really don't want to remove those docstrings

slate nacelle
#

We do not need those changes anymore.

vagrant holly
#

I replied to your review on that bit, I don't think it's sensible to skip normalizeFields completely

copper laurel
#

I'm pretty sure this issue comes from my last PR on this where I introduced normalizeFields into the constructor

#

So my bad on that - it was intended to address the fact that people would pass in partial fields via the constructor data, but not fail until they werent sent to the API

#

However that's clearly impacted the incoming embeds so reverting it seems fine

silk gust
#

can someone make a pr about the default avatars
user.avatarURL() =? nothing => Default Avatar URL

opaque vessel
#

Use .displayAvatarURL()

tough geode
#

I'm pretty sure it's like as it is on a purpose, it might be useful to know if someone has the default avatar or a set one. and ^, just use User#displayAvatarURL

drifting knot
#

is this a place to discuss d.js-next

#

if so, i have bunch of minor improvements to stuff like CI on it, should i make a single big PR for it or many PRs that only change a single thing?

wild flax
#

latter

drifting knot
#

cool

#

pr spam time

#

also ur eslint GH action is using src dir by default and borking the ci

wild flax
#

it won't use the action anymore

drifting knot
#

ok

wild flax
#

yes I am aware

drifting knot
#

cool

wild flax
#

but we don't have any code yet, so its not really relevant

drifting knot
#

got it

wild flax
#

i mean you can fix it if you want @drifting knot

drifting knot
#

i can try later

#

is it fine if the script is just raw ass eslint <files> and no pretty github actions integration

wild flax
#

yup

#

that was the plan anyway

drifting knot
#

cool

analog oyster
#

Crawl, .eslintrc.json could be removed from the file root and added to package.json as eslintConfig then

wild flax
#

no because it defines too many rules

#

we dont have our own shared config

#

and well likely not make one with the current rules

analog oyster
#

ok

drifting knot
#

@wild flax does it even make sense to have eslint running in the cron job?

#

also what is the plan for eslint config, make our own or use a premade one? (i like the XO ts config)

real jetty
#

not 100% sure if this fits here correctly:
Is there seriously any disadvantage of removing all users from cache? If someone messages the bot or writes a message in the channel, the bot receives the user info so it works without caching somehow.

So why not simply "uncaching" all users?

sick raft
#
var emb = new Discord.MessageEmbed()
        .setColor("#ff0d00")
        .setTitle("Title")
        .addField("Field: ", "Text", false)
        .attachFiles(["img1.png"])
        .setImage('attachment://img1.png');
        msg.channel.send(emb);

Is this intended behaviour or a bug? the path of setImage does not work when there are spaces. (example: if the image was named "image one.png" the image would still be attached to the message, but it will appear outside, above the embed)

drifting knot
#

as for you ishidres

#

caching is good if you need to query a bunch of users/channels/whatever but haven't had a presence update or smth come in to populate the data

sick raft
#

on the contrary, that's where I came from, I've been told to ask if this is a bug in discord or not

drifting knot
#

lmao

rigid trail
#

caching is essential, its faster than fetching, and it minimizes api calls

drifting knot
#

read their message burger

#

wait nvm im illiterate

rigid trail
#

the lib also relies heavily on some caches

drifting knot
#

yeah you need to cache stuff unless you want to get ratelimited by dapi

#

if you want to restrict caching their are options for it in the Client

copper laurel
#

@sick raft very unlikely to be a bug - if there's spaces in the URL it would be resolved as image%20one.jpg and wont be a match

#

Besides, even if t is a Discord bug, theres nothing we can do about it so it still isn't really a library discussion

sick raft
#

lol I see

#

but attachFiles works like a directory, not url lol

#

but ok

copper laurel
#

It attaches it to be referenced by a URL

wild flax
#

@drifting knot we already.. have one?

#

lol

drifting knot
#

eslint config?

wild flax
#

yes

#

we also have prettier already

#

and we are not using spaces

drifting knot
#

hmmmm

#

prettier config is copied from discord.js repo

wild flax
#

its already in the repo

#

same as the eslint config

drifting knot
#

hmmmmmmmmmmmmmmmmmmmm

#

where

wild flax
#

we only use prettier on lint staged

drifting knot
#

ok

drifting knot
#

damn i guess im illiterate

wild flax
#

so theres no reason to prettier the md files

#

nor the json files

drifting knot
#

surely there is

#

why only use prettier on some of the files

wild flax
#

because just as an example, the stuff prettier does to certain md files is not appreciated

drifting knot
#

fair

#

im on mobile rn and can revert those changes tomorrow

#

or if you'd like you can do it

wild flax
#

On the issue templates for example it weirdly merged the html comment and I had to manually fix it

#

Makes go a bit "eh"

drifting knot
#

weird

vagrant holly
#

👋

#

Is addFields or spliceFields ever used by the lib internally, or only by users?

warped crater
#

if something is marked as @private in the jsdoc it isnt meant to be used externally

#

private things wont even show up on the docs by default

#

besides that, unsure about internal use for those two

vagrant holly
#

I'll just add logic to be safe

#

¯_(ツ)_/¯

snow crypt
#

i dont think they are

#

ill scan source

#

@vagrant holly just embed and typings

vagrant holly
#

yeah, that was the conclusion I reached as well

#

I ended up adding the logic in anyway, who knows what the lib might do in the future, might as well have those methods patched

drifting knot
#

the collection module looks like it's the easiest thing to bring over to djs-next since it's already written in TS
does it need any refactoring or is it basically as easy as copy-pasting the file over?

another thing i'm wondering about is how unit/integration/e2e tests will be done.
will they be written in TS as well, or use the current method of JS testing with assert

wild flax
#

Yeah, it "seems" like an easy PR

#

but no, I'll do that manually

#

And tests will be written in TS too

drifting knot
#

cool

snow crypt
#

what test lib?

wild flax
#

jest

drifting knot
#

rly

#

but the globals 😡

wild flax
#

?

#

are you saying ava is better lol

drifting knot
#

i might be

#

or node tap

snow crypt
#

how do they even work

wild flax
#

ava is sadly bad, and so is XO

drifting knot
#

RIP

#

i like xo and ava

drifting knot
#

more questions:

  1. what service will we use for code coverage tracking? (ex. coveralls, codecov.io)
  2. what is the types package for? typings for the dapi and/or types shared between d.js projects?
warped crater
#
  1. dapi
drifting knot
#

last time i posted it shay said "bad" and never explained why

warped crater
#

shay is often not serious

#

theres not much to comment on that repo honestly

#

appel's spec-tacles has dapi types too

#

and so do I

drifting knot
#

ok

#

can we use fake opaque types for maximum type safety

warped crater
#

hell, looking at that repo it looks like a ripoff of spectacles cut into more files

drifting knot
#

i mean its typings for the same api

warped crater
#

I already asked Crawl about this, he said they'd just partly port appel's probably

drifting knot
#

ok cool

#

where are appel's types?

real jetty
#

Hey, so I am trying to implement throwing errors for empty embed names or fields

#

I edited addFields to this:

#
    if(!fields[0].name) throw new Error('EMBED_FIELD_NAME');
    if(!fields[0].value) throw new Error('EMBED_FIELD_VALUE');
    this.fields.push(...this.constructor.normalizeFields(fields));
    return this;
  }```
#

Then I realized that it just covers the first embed

#

If anyone would like to take over go ahead!

copper laurel
#

So, addFields calls normalizeFields which calls normaliseField

#

Which does throw a range error if Util.resolveString returns a falsey value

real jetty
#

It does not throw it, i've tested

copper laurel
#

Problem is, undefined will resolve to "undefined" which is a valid string, not falsey

real jetty
#

Yep

copper laurel
#

So maybe in that function, throw before resolving and after? idk

real jetty
#

Ye before resolving we can throw error

tired kindle
#

actually, shouldn't the resolver take care of it? (I'm unsure about d.js design but I think the resolver itself should throw, as ResolveStringNotNullOrUndefined or so)

copper laurel
#

Not sure I agree

#

undefined can be resolved to a string, as such

#

So it's doing its job

tired kindle
#

I mean, implement a new resolver for the field values where it checks if it's undefined or not and then calls toString

copper laurel
#

That's really what normalizeField already is

real jetty
#

Im PRing a fix

tired kindle
#

oh

real jetty
#

Question:

#

- [ ] does this make the checkbox ticked or not

tough geode
#

no
[x] - ticked checkbox
[ ] - non-ticked checkbox

real jetty
#

Ok done

vernal atlas
#

@copper laurel did you find out a way to fix the type guarding on partials in your PR?

copper laurel
#

Was never specifically in my PR, doesn't seem to work in v12 either

vernal atlas
#

hm

copper laurel
#

It should just be the boolean literals true and false, but it isn't working

vernal atlas
#

well best way i came up with is another union type for partials, which is each channel partialized,

type PartialChannelTypes = Partialize<Channel> | Partialize<DMChannel> etc```
copper laurel
#

Hmm

vernal atlas
#

i tried doing ChannelTypes | Partialize<ChannelTypes> but that just acted the same as before

copper laurel
#

That's also what I tried

#

Will look into it later

#

Did you see my replies on your last set of comments?

vernal atlas
#

yea

vernal atlas
#

@copper laurel i cracked it sorta

#
type PartializeChannel<T extends ChannelTypes> = {
    id: string;
    partial: true;
        fetch(): Promise<T>;
  } & {
    [K in keyof Omit<T, 'id' | 'partial'>]: T | null;
  };```
#

then PartializeChannel<ChannelTypes>

copper laurel
#

Ayyy I like that, ty

vernal atlas
#

👍

copper laurel
#

Hadn't had much chance to look into that part myself, I'll test that shortly

real jetty
copper laurel
#

@vernal atlas How is your partialize different to whats already there?

type Partialize<T> = {
    id: string;
    partial: true;
    fetch(): Promise<T>;
  } & {
    [K in keyof Omit<T, 'id' | 'partial'>]: T[K] | null;
  };

  interface PartialChannel extends Partialize<Channel> {}
#

Other than changing what gets passed in as the generic

vernal atlas
#

T extends ChannelTypes

#

whereas before it was just any

copper laurel
#

I dont understand why that fixes it but okay lmao

slate nacelle
#

Isn't that "just" a constraint?

copper laurel
#

Thats why Im asking, yeah

vernal atlas
#

🤷 not sure but it does fix the issue

slate nacelle
#

Just TS things I guess ✨

vernal atlas
#

also haven't tested but it might fix another issue with partials i pointed out

copper laurel
#

So ```ts
type Partialize<T> = {
id: string;
partial: true;
fetch(): Promise<T>;
} & {
[K in keyof Omit<T, 'id' | 'partial'>]: T[K] | null;
};

interface PartialChannel extends Partialize<ChannelTypes> {}
``` doesnt work, but changing it to T extends ChannelTypes does?

#

(well, not changing, but making another)

copper laurel
#

Yeah thats a bit of a larger question that implies there should be different Partializers for everything

#

...TS is now compiling fine without adding that additional constraint

#

I have no idea why I thought it didnt work for me before

vernal atlas
#

i tried testing it without the T extends ChannelTypes and it was yelling at me

copper laurel
#

Yeah it yelled at me too, or so I thought

#

But now I'm testing it without that, and it isnt yelling at me

#

Just using regular Partialize<ChannelTypes>

#

I also had to add partial: false to all the other channel types though

#

Noticed that was missing

vernal atlas
#

hm

copper laurel
#

Regarding your proposed change to Invite stuff

#

I think that's really out of the scope of my PR

vernal atlas
#

can a DMChannel be updated? aka emitted in the channelUpdate event?

#

pretty sure it can't right?

copper laurel
#

Since currently, GuildChannel#createInvite() is where that method is defined, so my typings are correct as it currently stands

#

I honestly dont know but I'd rather not block support for that in typings

#

The old event emit Channel so I'm keeping it equivalent, not trying to change things

vernal atlas
#

the type guarding with Partialize<ChannelTypes> isn't working here for me?

copper laurel
vernal atlas
#

oh thats because you fetch it

copper laurel
#

Well... yeah?

vernal atlas
#

and fetch returns the full object

copper laurel
#

Ahh i see

#

One sec

vernal atlas
#

and you can still send messages to a partial channel etc

copper laurel
#

Not according to typings

#

Okay, here's the way that didnt work

#

And doesnt work with T extends Channel either

#
if(!channel.partial) {
        if(channel.type === "text") {
            channel.send();
        }

        if(channel.type === "voice") {
            channel.join()
        }
    }
#

oh wait

#

explicit false check does work

vernal atlas
#

i get an error because partial doesn't exist on CategoryChannel

copper laurel
#

Yeah it does exist in my typings

vernal atlas
#

ah

copper laurel
#

Needs to be false, not falsey, thanks Javascript

vernal atlas
warped crater
#

huh, how does that happen

copper laurel
#

My typings will define that

#

Its only a property if it gets partialized currently

#

So I'm adding public readonly partial: false to them

warped crater
#

ah

vernal atlas
#

shouldn't it be partial?: true, since if its partial, it will be true, if not it will be undefined

warped crater
#

I tried to do this myself but failed miserably

copper laurel
#

But I'm defining it to be false

vernal atlas
#

oh i see

copper laurel
#

You started it on the right track

vernal atlas
#

👍

#

also, regarding this [K in keyof Omit<T, 'id' | 'partial'>]: T[K] | null; part of the Partialize type, this makes everything nullable right?

#

wouldn't that include functions? which aren't nullable

#

hm one sec

copper laurel
#

This is really starting to get out of scope of my PR

vernal atlas
#

ok im lost here now lmfao

#

[K in keyof Omit<T, 'id' | 'partial'>]: T | null;

T | null is meant to be T[K] | null

warped crater
#

hoold on Sugen

vernal atlas
#

and T | null is what's in my PartializeChannel

copper laurel
#

It is T[K] null?

warped crater
#

what is T over there, im on mobile

copper laurel
#

Yeah but Im not using that

vernal atlas
#

hold up lemme explain it fully

warped crater
#

no I get what you're trying to do

#

im just asking what T extends

copper laurel
#

In theory - anything

#

In this particular use case - channels

warped crater
#

okay but what does he actually pass into the generic

vernal atlas
#
    type PartializeChannel<T> = {
    id: string;
    partial: true;
        fetch(): Promise<T>;
  } & {
    [K in keyof Omit<T, 'id' | 'partial'>]: T | null;
  };```
the typeguard works fine with this
#

with T not extending ChannelType anymore

warped crater
#

and you're passing channel classes? meguhappy

vernal atlas
#

and instead T | null

warped crater
#

the Omit there wont work correctly

vernal atlas
#

instead of T[K] | null

warped crater
#

nevermind, I get it now, yup, that looks good

#

or does it

vernal atlas
#

T is a channel class tho, meaning that everything there would be a Channel

warped crater
#

why T | null

vernal atlas
#

exactly

#

but everything isn't a channel it seems

warped crater
#

yeah meguFace

#

T[K] should be it

#

but you end up making methods nullable NotLikeThis

vernal atlas
#

yeah you can fix that ez by doing T[K] extends Function ? T[K] : (T[K] | null) right

warped crater
#

as far as I know, no

#

maybe that syntax works

#

but for starters extends -> is :+1:

vernal atlas
#

hol up i think i got it

warped crater
#

similar to how Array#isArray is typed as (value: any): value is any[]

copper laurel
#

The typeguard is already working fine though

#

If you want to make less props nullable thats fine

vernal atlas
#

@copper laurel don't you need to actually define partial in the constructor tho

#

otherwise the typings would be incorrect

copper laurel
#

So maybe it should be partial?: true

vernal atlas
#

yeah thats what i was saying above

copper laurel
#

idk this is too hard lmao

vernal atlas
#

also would it be better to put it on the Channel class

#

instead of each class individually

copper laurel
#

Valuable learning experience for djs-next

vernal atlas
#

as they all extend Channel

copper laurel
#

Didn't work when I did that

#

idk why

#

Will try again, might just be VSCs fault

vernal atlas
#

see,what i did here

  type PartializeChannel<T> = {
    id: string;
    partial: true;
        fetch(): Promise<T>;
  } & {
    [K in keyof Omit<T, 'id' | 'partial'>]: T | null;
  };```
works, but its technically incorrect, as it defines every property as being a ChannelType, but if you combine it with ChannelTypes, `ChannelTypes | PartializeChannel<ChannelTypes>` it appears to have everything with the correct property values / return values
#

oops accidental enter

#

lemme edit edited

copper laurel
#

I still don't at all understand why we need a separate partialize

#

Because as far as my testing goes we don't

vernal atlas
#

yeah not saying we do just that what i pointed out earlier was a bit incorrect

copper laurel
#

It should be T[K] | null right?

vernal atlas
#

yea

copper laurel
#

Then yeah

#

We just need partial defined on the other channel types

#

At least as an optional property I think

vernal atlas
#

ig but the typings still need to show that the methods work on PartialChannels

copper laurel
#

Out of scope of what I was aiming for in this PR though

#

Unless I widen that

#

I'm mobile, lemme get to my desk lol

vernal atlas
#

hard to explain but i think it sort of is in the scope of the PR

copper laurel
#

So

#

Where are you suggesting ChannelTypes | PartializeChannel<ChannelTypes> belongs?

vernal atlas
#

i was suggesting that, but there needs to be another way

real jetty
#

hello is there a difference between updateoverwrites and createoverwrites they look like the same to me so why 2 for 1?

vernal atlas
copper laurel
#

Have you pulled down my latest commits?

vernal atlas
#

ye

copper laurel
#

So, is your concern here that methods dont exist on partials?

vernal atlas
#

yea

#

i suppose it could be out of scope if you put it that way

#

both methods and properties don't exist for each partial channel type

copper laurel
#

Im 50/50 - it wasnt my intention to change how partials work

vernal atlas
#

ok

copper laurel
#

Just to typeguard based on the existing implementation

#

Which currently, if not partial, can use channel

vernal atlas
#

maybe ill do a PR for fixing the partials ig

copper laurel
#

@vernal atlas ayy I tracked down why this shit doesnt work properly

#

Channels don't have a getter to determine when they're partial or not

vernal atlas
#

ah

copper laurel
#

is the assumption that other channel types are never partial?

#

Yeah according to docs

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.

vernal atlas
#

so should channel events just not even emit a generic partial

copper laurel
#

DMChannels

#

Can still be partial

vernal atlas
#

yeah, so instead of emitting a PartialChannel, it should emit a PartialDMChannel

copper laurel
#

I'm leaving that alone for now

vernal atlas
#

everything with an id has createdAt right?

rigid trail
#

it should yes, since you can get a timestamp from the snowflake

vernal atlas
#

yea

copper laurel
#

The docs on partials say this though

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.

vernal atlas
#

yeah, that should be changed because of the ID, and some methods do work normally

#

like sending a message to a channel

#

i don't see what the channel being partial could effect there?

#

maybe theres a better example but you get my point

copper laurel
#

I think like

tough geode
#

oh, right

slate nacelle
#

@tough geode another reason would be that the id of the client user is not necessarily the id of the application.
This is only the case for very old applications however.

ornate topaz
#

(Nadeko bot would be one example)

vernal atlas
#

i can't seem to get TS to recognise that messages is meant to be an array?

#

using the normal send overloads, not from my PR

spice lava
#

you can cast it <Channel>.send().then(msg => (msg as Message[]).length ...)

vernal atlas
#

should have explained but, i made a PR to remove some duplicate types as parameters for the send overloads, but then crawl commented saying that would break it, but i can see the overloads arent even working as they should in the first place @spice lava

#

so, not trying to fix an issue on my end, but with the send overloads

#

i think i found the problem, the overloads with only options need to be defined first, i think its something to do with the fact StringResolvable is any

snow crypt
#

i pointed that out earlier

#

because send takes StringResolvable it would not autocomplete or type check

vernal atlas
#

ah

solemn kite
#

are intents fully implemented yet?

#

I imagine the new cache way is to make way for the intents system instead because cache is gonna be redundant at some time

#

... right? cause I assume its gonna be because of the intents you're unable to really make sure that the dats you have in the cache is gonna be there so its gonna be deprecated soon?

copper laurel
#

Uhh, no?

#

Just specify all the intents so that we can cache stuff

#

Intents are available but not yet required

#

But there are some issues where if intents arent specified cache will be missing, yes

ornate topaz
#

Even if missing, it will definitely not be redundant though. That would mean that bot doesn't cache literally anything at all, while you can just use the intent to get data for cache back again (assuming your bot will be allowed to use all intents)

analog oyster
#

'none' | 'all' | 'everyone' aren't types PES_Hands

real jetty
#

No the typings are correct, they are valid types in TS

#

You just didn't use it correctly

#

What is the code you tried?

analog oyster
#

what can I even do about this

real jetty
#

Yeah like that, now you're encountering "type widening"

#

You can do disableMentions: 'everyone' as 'everyone'

analog oyster
#

oh, thank you

#

sorry for coming to the wrong channel ig

copper laurel
#

Or define CLIENT_OPTIONS as ClientOptions

#

Might also work /superlate

thorny cosmos
#

Ok, I just came across something, <Guild>.verificationLevel returns a VerificationLevel typedef, which has a type of String

#

However, when I see the typeof this thing, it says it returns a number actually

#

same goes for the ExplicitContentFilterLevel and so... I don't know if this was done with intention for showing the string type in the respective methods which takes a parameter as a string | number, I think it would be better if the numbers are shown along with the Level alongside in the TypeDef and make the Types as string | number

real jetty
#

version 12 of discord.js is a poop

opal mauve
#

please don't randomly complain here. this channel is for serious discussion about the library.

vernal atlas
#

@thorny cosmos oh, i think that came from a PR i made, maybe a merge conflict or smth changed it without realising

#

interesting

#

hm

#

@thorny cosmos i assume you are talking about

#

because it looks as it should to me

#

perhaps your version is out of date

thorny cosmos
#

Oh, you are right@vernal atlas , I realised i am using an older commit of v12, well, will update then

vernal atlas
#

👍

green sentinel
#

I think Channel should have a partial field, since when you use client.on("channelUpdate",...) you get a Channel | PartialChannel.

#

I use typescript so to check if the channel is partial I either have to just channel.fetch() or do something like

(channel as PartialChannel).partial ? channel.fetch() : channel as Channel;
vivid field
#

DMChannels have a property showing if it's a partial or not, other channels are never partials as guild channels are always cached

raven juniper
#

you can remove guild channels from cache

green sentinel
#

I think it just makes sense to put a partial property on a value that can possibly be partial. Call me crazy.. lolol

copper laurel
#

Theres already a PR in place for this

#

GuildChannel#partial will always return false
DMChannel#partial will do the appropriate check
Typings will be improved so directly handling the Channel class shouldnt happen, since its supposed to be abstract

tough geode
opaque vessel
#

Probably

#

It's specified in the typings as such

unique axle
#

this channel is for library discussion not support

split steeple
#

sry

finite rover
#

is there any reason djs doesn't use ms precision ratelimit?

tired kindle
#

you can't you don't receive milliseconds precision from the API

#

it's in seconds, from the Discord API

opal mauve
#

@finite rover discord.js does use ms precision

finite rover
#

it's in s unless you tell it to give you ms

#

@opal mauve would you mind showing me the relevant line?

#

i ctrl-f ed the repo to find where the x-ratelimit-precision header was and I couldn't find it but maybe i missed smthing

opal mauve
#

@finite rover oh, my bad. it's included in @tacit crypt's REST PR which is still in draft form.

finite rover
#

yeah exactly what i found as well

#

so any reason this hasn't been introduced sooner?

#

it shouldn't imply much change apart from sending the additional header right?

tacit crypt
#

It wasn't really needed?

opal mauve
#

the PR that's adding it isn't finished yet

tacit crypt
#

I mean you're not gaining SO much speed from it

finite rover
#

that's fair, honestly I'm purely asking for information here

tacit crypt
#

Maybe I'll actually finish that PR one day

#

After rewriting the entire bucket system...again

finite rover
#

I was not even talking about the PR that seems to introduce much more than just ms precision

#

I was mostly wondering if adding ms precision would needmore changes than it seems

#

and that maybe I don't know about

tacit crypt
#

I mean, to keep it simple

Can we use it? Absolutely
Should we? Probably?
Is it that important we use it? Not really
Is it gonna need massive changes? Nop, one liner. Testing tho... Yike

finite rover
#

Alright

#

thanks for the answer

#

That's what I thought, I wanted confirmation thank you

#

Also yes I guess it doesn't matter that much theshrug

real jetty
#

I have been thinking. But in the message reaction remove event, when fetching cuz it's a partial. this.emoji could be a guild emoji what could trigger the error. But why does message reaction add event doesn't have that problem? think

real jetty
#

@real jetty I'll be opening a pr today that fixes this issue with an explanation to y all this mess happens

#

Okie

real jetty
#

There is a lot of text and stuff but basically you use only messageReaction.fetch() where it would also fetch the message automatically? (if the message was also partial) (In the new solution such to speak)

#

yh thats pretty much wat it was doing before, now it just uses Message#_patch() to end up with the same result

#

u would only use MessageReaction#fetch() if u care about the count prop otherwise u prolly just wanna fetch the message depending on wat ur doing

alpine pier
#

I might be stupid but why is TextChannel.members not a GuildMemberManager like Guild.members but a normal Collection instead?

rigid trail
#

because its a getter, which means it would have to be a pseudomanager, and it would also be redundant with the guild's member manager, overall its just not really worth it, at least in my opinion

alpine pier
#

I see. Thank you meowmeltthumbsup

vernal atlas
#

would it make sense that the 'newMessage' in messageUpdate technically couldn't be a partial?

#

listening to the 'raw' event, i see that the full object seems to be sent by the websocket, which is enough to construct a full message right

slate nacelle
#

More of an edge edge case:
If you receive an embed update for a partial (or uncached) message, you would only have relevant ids and embeds.

vernal atlas
#

ah

real jetty
#

yo is there an API for the discordjs.org website that returns info of the docs in JSON, kind of like how NodeJS docs has a "View as JSON" format?

slate nacelle
real jetty
#

thanks

frozen bridge
#

haiya! I was wondering how long it takes issues to be looked at and fixed.

rigid trail
#

it really depends on how complex, how big of a change it is, and if there are people who bother to fix it ¯_(ツ)_/¯

copper laurel
#

Discussing it here/general (if its a feature/change) or in support (if its not actually an issue with the lib) would speed things along

#

Since it gets more eyes looking at the problem

ornate topaz
unique axle
#

My stand on that: either everywhere or nowhere
In the past we've always come to the conclusion that discord.js should not document upstream permissions, as they weren't even clearly documented to begin with. Discord has now fully documented permissions on the API documentation per endpoint.

However since we recently introduced the permission and hierarchy matters this might have changed.
If we really want to start documenting permissions I'd personally be in favour of adding a link to the used API endpoint rather than just the permissions as part of the method description. If that is even needed/wanted however is another point of discussion

frozen bridge
#

Staff have seen it

#

just wondering how long it will take to be fixed

#

as I can't keep a shard offline for too long

wild flax
#

There is really not enough information to even figure out where its starting or coming from currently

#

Despite the high priority it has

frozen bridge
#

Any way I can help ya get info or something

wild flax
#

cc @slate nacelle maybe you have a better general idea where this could come from and know which information we'd need

#

cc @tacit crypt

tacit crypt
#

I..

For one, can you get me debug logs from the shards, especially those that error?

manager.spawn(20); // Start 4 Shards

This spawns 20 shards, not 4, try changing that?

#

As for errors like Error: Something took too long to do I have NO idea where it's coming from. Check your code to ensure it doesn't have many hanging loops..

slate nacelle
#

My thesis is that this is caused by a guild not being available (presence limit reached or discord outage, probably #1).

In detail:

Error: Something took too long to do.
This is a Client (shard) error.

Thrown on v11, once a timeout elapsed before all guilds were ready.
(Nothing you can do about this on v11 sadly.)

That was taken care of with v12 by readying the client after a (different) timeout instead of erroring.
(You'll have unavailable guild(s) then though, but that's probably not an issue, d.js-wise)

Error: Shard 1's Client took too long to become ready.
This is a ShardingManager error.

This timeout can be disabled by setting the spawnTimeout to -1 or Infinity, may not be the fanciest solution, but should work.
https://discord.js.org/#/docs/main/stable/class/ShardingManager?scrollTo=spawn
(Nothing you can do about this on v11 sadly.)

frozen bridge
#

@tacit crypt Same issue with 4, used 20 to make sure that only 1/20 of the servers had the bot down

tacit crypt
#

Can you check the debug log for each shard?

frozen bridge
#

I tried debug, nothing was wrong

#

I can start it with debug and send ya the logs 1 sec

tacit crypt
#

Please do

frozen bridge
#

The issue persisted in v12

#
Sharding Manager ➜ Launched shard 1
Shard 1 ➜ Using gateway wss://gateway.discord.gg/?v=6&encoding=json
Shard 1 ➜ [ws] [connection] Connecting to wss://gateway.discord.gg/?v=6&encoding=json
Shard 1 ➜ [ws] [connection] Identifying as a new session
Shard 1 ➜ [ws] [connection] Connected to gateway wss://gateway.discord.gg/?v=6&encoding=json
Shard 1 ➜ [ws] [connection] Setting a heartbeat interval for 41250ms
tacit crypt
#

thats v11

#

i'm asking for v12

frozen bridge
#

o

#

1 sec

#

Hmm it seems to be working now

#

If I get an offline guild ill try again

tacit crypt
#

owo 👍

copper laurel
#

Sorry, why was I pinged here? Is this relevant to me? I don't understand the sharding at all lol

frozen bridge
#

Nope not anymore

#

@tacit crypt Yep it seems to work now, it just takes like a minute longer than the other shards. What could be causing this? (Nothing specifically singles this shard out in the code)

tacit crypt
#

Because we wait for all guilds to come in. However, due to unavailable guilds, we wait 15 seconds. Aka

Say you have like 1000 guilds, and 5 are unavailable. We set a timer for 15s to mark the shard as ready regardless if all guilds came. We refresh that timer every time a guild comes. Once all but the last unavailable guilds came, the timeout takes over.

clever crypt
#

I keep having problems with one unavailable guild - 7100 members.

Sometimes it doesn't come through until 60 seconds after coming ready, sometimes it's perfectly fine.

fallen arrow
#

and this 15s timer is present in v12 but not v11, correct?

#

the solution i came up with is to manually run client.ws.connection.triggerReady(), not sure if its the best workaround

tacit crypt
#

I keep having problems with one unavailable guild - 7100 members.

Sometimes it doesn't come through until 60 seconds after coming ready, sometimes it's perfectly fine.
@clever crypt blame discord

warped crater
#

^ literally nothing you can do about it

#

after Discord's ready event they begin sending you guilds in the form of GUILD_CREATE packets

#

all d.js does is process them

glass hamlet
#

Thanks @fallen arrow , that workaround is working partially for me. Gonna have to work with it for now

lofty birch
#

So am I correct in thinking that the ready event is emitted when the bot connects, and the shard ready event is emitted when all of the guilds have been sent?

fallen arrow
#

should be the opposite afaik

lofty birch
#

Ah ok

real jetty
#

https://discord.js.org/#/docs/main/stable/class/User?scrollTo=toString

When concatenated with a string, this automatically returns the user's mention instead of the User object.
That's not true, when doing someString + user, the valueOf method is used, resulting in the userID.
https://github.com/discordjs/discord.js/blob/stable/src/structures/Base.js#L37-L39
Doing somestring ${user} or user.toString() does work as expected, but still, I think the word "concatenated" isn't the right word for it.

old kelp
#

I'm having a problem understanding the version 11.6.3 and 12.00

#

like what are they both

#

and as I know, master is the version 11.6.3, right?

frozen bridge
#

@wild flax wyd ya reopen?

wild flax
#

I commented.

frozen bridge
#

o

#

yea just saw

#

One of the devs above thought that there was nothing we could do about it?

#

nope I misread

fallen arrow
#

the only thing that could be done about it is to give it the same timer that v12 uses

real jetty
#

return { guild };
What is the point in having the above over this:
return guild;

deft holly
real jetty
#

Yea that is a line in the library

deft holly
#

that's a question about the library code, but the answer would be it returns an object (shorthand for { guild: guild }), as to why, depends on context

real jetty
#
message.channel.bulkDelete(2, true)```
works but return this error 

(node:2068) UnhandledPromiseRejectionWarning: DiscordAPIError: 405: Method Not Allowed

#
 
  name: 'DiscordAPIError',
  message: '405: Method Not Allowed',
  path: '/api/v7/channels/%3C',
  code: 0,
  method: 'POST' }```
#

Whats weird is from where %3C came from

raven juniper
#

Without knowing the context, that sounds like it's in a DM

slate nacelle
#
  • %3C is an encoded <
  • This method does not even hit that endpoint (POST /channels/:id)
    (It impossibly could result in that error)
  • Bug reports should go to our issue tracker instead
    (This does not include enough info though, see point 2)
clever crypt
vernal atlas
#

doesnt seem to throw an error

#

but then again doing v9999 doesnt throw an error either

ornate topaz
#

some people say v7 is "out" for multiple years now, but discord can't justify releasing it

tacit crypt
#

v7 of rest is like v6 of rest but with better errors

vivid field
#

Probably a rather nooby question, but why doesn't TextBasedChannel extend a regular Channel?

warped crater
#

its an "interface"

#

and it's being implemented into whatever channels are "text based"

tough geode
#

/\, it's never constructed, whatever it's implemented into in the lib extends Channel

warped crater
#

in short, it's a class but its not used the "normal" way

real jetty
#

guild.channels.create(name, options) and guild.roles.create({ data, reason }), I'd say it's better if GuildChannelManager#create would only accept one argument

opaque vessel
#

Huh? It already does, the options are optional and the type defaults to a text channel

real jetty
#

No I mean like guild.channels.create({ name: 'somevoice', type: 'voice', permissionOverwrites })

#

I'd say it's more consistent with other methods

raven juniper
#

The object is for optional parameters, the name is not optional for channels, it is for roles (apparently)

#

You see the same format in emojis.create(), first parameters are required, and then an object for optional ones

real jetty
#

Ahh so that's the logic behind it

ornate topaz
#

regarding roles, discord defaults to new role name, additionally, it's name every role you create in app had at one point, since you can rename it after you create it

thorny copper
#

I tried to update my bot to v12. It's horrible how Typescript's support has become worse than v11

#

Some examples:

clever crypt
#

Manager#cache is a collection, which is an extended Map.
Typings for that would be for (const [id, channel] of server.channels.cache).
If you wish to loop over just the channels suffix the .cache access with .values().

clever crypt
#

This is more of a support question that a complaint/suggestion/nit about the package.

thorny copper
#

with .values()

#

I did find a solution tho

#

(server.channels.cache.array() as GuildChannel[])

clever crypt
#

I have no problem with this code

for (const channel of <guild>.channels.cache.values()) {
    console.log(channel.permissionOverwrites);
}
``` *edited for your use case
thorny copper
#

I don't think there is, but TS grabs it as a "any" type

clever crypt
#

More or less a problem with your code editor

thorny copper
#

Another fantasy

#

And this one is really from DJS

#

fetch method doesn't take any arg, right?

clever crypt
#

Correct

umbral aspen
#

If you're calling fetch on the message, then yeah.

clever crypt
#

What is message?

thorny copper
#

client.on("message", (message) =>

umbral aspen
thorny copper
#

@umbral aspen Actually I complaint more than I ask for help :x

real jetty
#

For the collection loop, it should work fine on es6, how does your tsconfig look?

umbral aspen
#

You seem to be asking questions that belong in the variety of subjects discussed / asked (about) in support center.

thorny copper
#

Sorry

spice lava
#

We have GuildMember#bannable would there be a place for a general method like GuildMember.canban(GuildMember) for example. Or is this too high level same as addBlankField was removed

Edit: or would comparing roles positions by highest roles of each member be the preferred method without a custom implementation

rigid trail
#

i really do not see a use for this

#

why dont you just check .bannable on the memberThonk

#

the last thing the lib should do is make wrappers for already kind of iffy permission getters blobsweats

spice lava
#

As that would only count for the bot, as said this would be quite high level

rigid trail
#

you want to see if a member can ban another? lol

#

again, dont see a use for it

#

its too specific of a method to be justified to be added, especially when it has no direct correlation with things the bot is doing

spice lava
#

That's why I asked. Alright!

sly pollen
#

Does djs use cluster module for sharding or no?

#

And does it scale to the number of cores available?

opal mauve
#

the node cluster module isn't particularly useful for sharding

#

d.js uses normal child processes

sly pollen
#

any reason why you guys wanted to go with normal child processes?

#

one thing i noticed about internal sharding is worker threads

#

would a build of several process that have several worker threads(shards) be a bad idea?

#

it's like a mix of internal sharding and process sharding except that you can get the most out of these processes?

opal mauve
#

we went with child processes because we didn't need the functionality of the cluster module

sly pollen
#

ah i see, but what about a mix between process sharding and threads sharding?

opal mauve
#

unsure what advantage that would bring

sly pollen
#

Instead of having 10 child processes with their own independent instances and their own memory being shards
We get to have 3 processes with 4 worker threads for each. These worker threads being shards (and every 4 worker threads do share the same memory)
instead of 10 child processes being shards, we get 12 workers being shards and only 3 processes

#

thats what i meant

undone ravine
#

@sly pollen workers don't share memory with the main thread

copper laurel
#

Does anyone know why the message event shares typings with messageDelete | messageReactionRemoveAll?

public on(
  event: 'message' | 'messageDelete' | 'messageReactionRemoveAll',
  listener: (message: Message | PartialMessage) => void,
): this;

When would client.on("message") emit a PartialMessage?

#

I can't think of a reason, so I feel like it should have its own typings

real jetty
#

yh it should just be typed as Message. it never will be a partial within the message event, the author and content fields will always be present there so Message#partial will always be false

frozen bridge
#

Haiya! I'm wondering if this is a bug or not... in djs 12.0.2, setting the position of a category to 0 puts it at the bottom of the channels, while setting it to 1 puts it under the channel in position 0

#

im using guild.channels.create

slate nacelle
frozen bridge
#

Then why is setting the position to 0 having the category created at the bottom of the channel list?

#

guild.channels.create("Covid-19", {"type": "category", permissionOverwrites: [{id: guild.id, allow: "VIEW_CHANNEL", deny: "CONNECT"}], "position": 0})

rigid trail
#

this is not at all the place for that question

copper laurel
#

This is not a support channel

rigid trail
#

you mean client#voiceStateUpdate?

#

it includes a voice state which has guild info..

#

not the right channel for this

#

please use a support channel

clever crypt
#

?gotosupport

rigid trail
#

on stable its a VoiceState for both params and on v11 its a guildmember so im not quite sure what you are suggesting

#

anyways its kind of offtopic since at this point its a code issue, not a library issue

copper laurel
#

reaction.count isn't showing in docs on 12.0.2 for some reason

#

Possibly because // eslint-disable-next-line eqeqeq has been added between the JSDoc and the property?

slate nacelle
uneven dawn
#

I'm not sure the best practice on this, but instead of having a generic type like GuildChannel that's defined to extend Channel , shouldn't there be a GuildTextChannel that extends TextChannel etc.?

This way you don't have to cast everything that comes as GuildChannel to the text/voice/category/news/store equivalents

rigid trail
#

so:

GuildTextChannel ---- TextChannel ---- GuildChannel ---- Channel```? what about DmChannels, those simply extend Channel and implement TextBasedChannel, similar to TextChannel which extends GuildChannel and implements TextBasedChannel
#

you will still have to cast, some methods can return any channel, say grabbing a channel from the GuildChannelManager, it can be text/voice/category, etc, so i fail to see how that solves anything, it seems to just add more clutter to inheritance

copper laurel
#

Channel typings will definitely be improved in v13 with proper typescript

snow crypt
#

I think messages could implement a guild typeguard

wild flax
#

Like the non-working channel typeguard?

snow crypt
#

I really don't know, but something to tell TS that if message.guild is present, message.channel is a TextChannel

plucky jay
#

I don't think a typeguard like that is possible with TS

#

But maybe a GuildMessage or something?

snow crypt
#

was about to say

wild flax
#

That falls under what borger said right at the top there

snow crypt
#
type GuildMessage = Message & {
  guild: Guild;
  channel: TextChannel;
  member: GuildMember;
};

type DMMessage = Message & {
  guild: null;
  channel: DMChannel; // can be partial(?)
  member: null;
};
``` and rest
#

some methods can return any channel

#

@wild flax why would that fail for message?

wild flax
#

oh

snow crypt
#

so would that work?

#

also, the channel typeguard works?

slate nacelle
plucky jay
#

@snow crypt But if you use message.guild instead, of message.channel.type === 'text', it won't work

snow crypt
#
type GuildMessage = Discord.Message & {
  guild: Discord.Guild;
  channel: Discord.TextChannel;
  member: Discord.GuildMember;
};

type DMMessage = Discord.Message & {
  guild: null;
  channel: Discord.DMChannel; // can be partial(?)
  member: null;
};

type AnyMessage = DMMessage | GuildMessage;

// @ts-ignore
const m : AnyMessage = get();
if (m.guild) {
  m.channel.permissionsFor
}
#

this works

tough geode
umbral aspen
#

I think it should be nullable since a category doesn't necessarily need to have any children channels. In other words, a category can be empty.
This perhaps should be updated to it not being marked as nullable, or updating it so it is nullable and that it returns a collection with entries present in it or null.

tough geode
#

categories can be empty, but .children is an empty collection for empty categories, not null, therefore it's misleading in my opinion.

thorny cosmos
#

Yes, 1s3k3b is right, the jsdocs for .children is kind of wrong, since collections extend maps, they can give an empty collection object if no key value pair exists, here is what I just evaled on an empty category
Also the typings on Collection states that Collection#filter() returns a Collection, not ?Collection, so it makes sense for why should it not return ?Collection<Snowflake, GuildChannel>

snow crypt
#

speaking of CategoryChannel, the setParent method is documented (because of GuildChannel), but it shouldn't be there at all

tough geode
#

well, it's inherited, but it has a warning

snow crypt
#

it doesn't have

#

same thing for lockPermission

unique axle
#

CategoryChannel#setParent should be there because the API technically allows it, despite throwing an error at this moment in time
Hence why instead the warning is introduced

snow crypt
#

and what would it do?

unique axle
#

as i just said, at this moment in time you can not tier categories like a file system, however the endpoint is there, so we decided to support it

snow crypt
#

but it does practically nothing?

unique axle
#

throwing an error at this moment in time
would not describe that as "nothing" per se

snow crypt
#

i'm talking discord

#

like, you can set a topic to a voice channel with djs, but it really does nothing if you look at it practically

unique axle
#

i fail to understand what you mean, the API throws an error, the request is rejected

snow crypt
#

the api throws an error when trying to set a parent?

#

does the api throw or is it just the lib?

slate nacelle
#

Depends on the error class you catch:
DiscordAPIError -> Discord threw it
DiscordjsError -> discord.js threw it

unique axle
#

as said, API error, to be more precise:

DiscordAPIError: Invalid Form Body
parent_id: Categories cannot have subcategories

snow crypt
#

well isn't this going with the head in the wall?

#

making a request that is going to fail is very strange to me

wild flax
#

its not worth it to specifically handle that use case or somehow remove it from the documentation despite its inheritance

snow crypt
#

but the library is there to interact with discord

#

could also split it to have a base GuildChannel, and a ParentedGuildChannel to have setParent on it, then have voice and text inherit from it, and categories would inherit from the base GuildChannel with no setParent

ornate topaz
#

but the library is there to interact with discord
Well, it's a wrapper for Discord's API, so theoretically, if CategoryChannel#setParent is documented in API, there is no reason to not have it. It might reject today, but what if tomorrow discord will release subcategories?
It's a wrapper for whole API, not wrapper for some of its functions

copper laurel
#

It exists because the API doesn't actually have different endpoints for different channel types the way Discord.js does. There isnt even a "set parent" API endpoint. Its literally just Modify Channel, specifying a parent_id
https://discordapp.com/developers/docs/resources/channel#modify-channel

setParent() is already just a helper function around an edit call really. The most logical place to share this inheritence is GuildChannel otherwise we'd be duplicating code across Text/Voice/News/Store channels

digital hawk
#

it doesnt play well with custom events and my event loader

#

i think having a [event: string]: any[] at the end of ClientEvents could potentially fix it

copper laurel
#

Makes sense to me - I think we've effectively locked it down too far

slate nacelle
#

You can augment the interface adding your own events there:

declare module 'discord.js' {
    interface ClientEvents {
        foo: [Map<string, any[]>];
    }
}

(Or that catch-all clause, too.)

snow crypt
#

I think it should be event: string | symbol in the all-catch

#

now how do i make a pr again

slate nacelle
snow crypt
#

so I guess we're not adding it back?

slate nacelle
#

I'd be in favor to not do that.

snow crypt
#

I'll do a pr with that note

wild flax
#

This doesn't make a lot of sense

#

why would you not extend the interface?

#

Why would you want to just allow any symbol or string?

snow crypt
#

as written in the pull, i'm just waiting for feedback

wild flax
#

You got feedback from 2 devs

snow crypt
#

why not more ¯_(ツ)_/¯

vivid field
#

Probably more of an api question, but is there a reason why guildMemberRemove gives you a member object whereas guildBanAdd gives you a user object?

rigid trail
#

hackbans

#

you can ban a user by id which is not in the guild (see: Guild#members#ban())

snow crypt
#

I would not be surprised if member.ban calls member.guild.members.ban

#

aaand... it does

rigid trail
#

why would it not

digital hawk
#

@slate nacelle I went ahead and just made my own interface in my bot which extends ClientEvents but I guess adding it in a d.ts works too

snow crypt
#

so do i close the pr?

#

yep

tender surge
#

Wish intellisense would still work if you allowed anything but yea if you allow anything now you either don't get autocompletion or you can't get the typings that are returned from each event

#

Also if you extend now you can easily type what's returned from your custom event instead of asserting

snow crypt
#

Would v11 break if moved to node-fetch?

warped crater
#

otherwise it would have been done already

tacit crypt
#

Would it break? No.
Would it be breaking? Yes

undone ravine
#

It wouldn't be breaking

tacit crypt
#

breaking from a semver point, no?

rigid trail
#

if nothing changes on the public API then i dont see how it would be semver major

undone ravine
#

No, unless there are points where raw return values are given to a user from snekfetch/node-fetch

#

Changing dependencies is not a breaking change

slate nacelle
snow crypt
#

if nothing changes on the public API then i dont see how it would be semver major
that's why i'm asking

rigid trail
#

i mean, i believe there is little to be gained from switching to node fetch but a significant amount to lose if done improperly, also, v11 isnt really in development as much as v12, as long as snekfetch works i dont see a need

real jetty
#

Would there be any way of adding in where an API call failed in the code? As in, more detailed stack traces

#

So instead of it coming from the library it would come from a method called from code the user had written

rigid trail
#

you mean unhandled promise rejections? not really no, as async code is run in parallel to the stack elsewhere, therefore stack traces are hard to make and would be huge

exotic flicker
#

v11-dev had a way to show accurate stack traces, but afaik node always had this missery with async stack traces

real jetty
#

then what changed between v11-dev and now that required that code to be changed?

#

well, ok probably a lot in all fairness but

exotic flicker
tacit crypt
#

My implementation in that PR you linked @slate nacelle would only work on v8 sadly (which would be fine if we didn't have browser builds); it's to be changed

slate nacelle
#

So basically like appells comment said.

tacit crypt
#

Well, yes but actually no

tacit crypt
#
TypeError: timeout.refresh is not a function
    at GABClient.handler (C:\Users\GAwesomeBot\Development\node_modules\discord.js\src\stores\GuildMemberStore.js:210:17)
    at GABClient.emit (events.js:323:22)
    at GABClient.EventEmitter.emit (domain.js:482:12)
    at Object.module.exports [as GUILD_MEMBERS_CHUNK] (C:\Users\GAwesomeBot\Development\node_modules\discord.js\src\client\websocket\handlers\GUILD_MEMBERS_CHUNK.js:18:10)
    at WebSocketManager.handlePacket (C:\Users\GAwesomeBot\Development\node_modules\discord.js\src\client\websocket\WebSocketManager.js:391:31)
    at WebSocketShard.onPacket (C:\Users\GAwesomeBot\Development\node_modules\discord.js\src\client\websocket\WebSocketShard.js:437:22)
    at WebSocketShard.onMessage (C:\Users\GAwesomeBot\Development\node_modules\discord.js\src\client\websocket\WebSocketShard.js:295:10)
    at WebSocket.onMessage (C:\Users\GAwesomeBot\Development\node_modules\ws\lib\event-target.js:120:16)
    at WebSocket.emit (events.js:311:20)
    at WebSocket.EventEmitter.emit (domain.js:482:12)``` If anyone wants to have a look, I'm a bit busy ![sad](https://cdn.discordapp.com/emojis/585885410257928194.webp?size=128 "sad")
rigid trail
#

GuildMemberStore 🤔

tacit crypt
#

yes, i'm not on latest cause we're rewriting soon

rigid trail
#

what node version are u running? cause timeout.refresh was added in v10

tacit crypt
#

nodejs 12.something

#

OH