#archive-library-discussion
25085 messages · Page 24 of 26
Otherwise you could just use raw js
Nothing is stopping you there
That will always be an issue with ts
People want type safety and strictness but not deal with types to a certain degree
Seems like a huge clash of ideologies
Yep I'm not saying to loosen type strictness, only that right now it requires some underlying knowledge of the types to use properly (ie. understand that MessageActionRowComponentBuilder is part of the AnyComponentBuilder union). It's not as easy to use as v13, or even previous versions of v14. Especially since the ts errors, in part with the types themselves being confusing, aren't the most amazing.
realistically the types will always be confusing (if accurate) because of the complexity of those data payloads
you do end up with very convoluted generics and deep inheritance on all those interfaces but at the end of the day
only that right now it requires some underlying knowledge of the types to use properly
so long as you understand the type system and are familiar with the data the method takes and what properties it accepts depending on other properties (e.g. the component type), it really shouldn't be all that much of an issue
It won't be as simple as v13 as we bring in strictness. That's a given no matter where its implemented or how.. and I'm sure if you asked there's probably someone in here that can guide you
I'm sorry to interrupt, this is just a simple question can we backport https://github.com/discordjs/discord.js/pull/7507 into v13 or add back the rule that was removed in a commit in v13 so that we can get the old casing on commits back? Also if so, which one of these options would yall prefer?
Sincerely, if I want to send an embed in response to a command, but don't want to use an EmbedBuilder because it's slow, than I'll simply use a raw JSON embed... Why should I use new UnsafeEmbed().setAuthor({ name: "idk" }) when I can use { author: { name: "idk" } } (and djs still provides types for that since there is the fantastic discord-api-types)
Yes we've been over this. It's not realistic for people to rewrite massive portions of their bot to do this.
I've been working on my bot since around august 2020, so there is a lot of maintenance going into it just for a v14 upgrade (many thousands of lines already), I can't realistically be expected to remove hundreds of embeds... EmbedBuilders.. UnsafeEmbedBuilders.. and replace with json. It would take days lol
So just keep using the builders as is..
I'm addressing his point because I hate that argument ("if you don't like it just simply don't use it")
Backport commitlint rule
I see what you mean, since I've already done big rewrites for my bots and that's why I started using raw JSON embeds. It's surely another refactor but... probably the last as I don't think (and hope) djs will drop raw JSON support and if you're lazy you can continue using a Builder, which is surely totally safe with its validation.
I'm not saying Unsafe*s should be removed, just that, as we just said, "If you don't like it, don't use it", there's no much difference at the end...
Why don't GuildAuditLogsEntry objects have targetId and userId or executorId properties?
Because the API returns full user objects when you fetch audit logs, theres no need to rely on cache getters based on id
But I checked the source code and it looks like it's just setting it with data.user_id and data.target_id
I mean I guess it could be converted to cache getters
https://github.com/discordjs/discord.js/blob/988a51b7641f8b33cc9387664605ddc02134859d/src/structures/GuildAuditLogs.js#L170 caches all the users returned in the payload when they're fetched
https://github.com/discordjs/discord.js/blob/988a51b7641f8b33cc9387664605ddc02134859d/src/structures/GuildAuditLogs.js#L387 the _add call on this line would return an existing user if one was in cache anyway, which they would be due to the above, same for target
silly question here - why does Base#_update() return a clone of the original object rather than the updated, patched version?
like, why would you want to continue using the old object after updating it
patch cache, return pre-update clone so you can still emit both in before/after events
ahh that makes sense ty
how about Base#_patch()? this implementation seems kinda useless, why not have this be abstract and throw an error if someone tries to call it?
it's overwritten by other classes that extend Base, that's an abstract method
ig they just dont want that error to be thrown
it seems like all the other implementations of this in the library don't return anything, so it seems weird to me that this one does return something
yea that's what I thought, I was just wondering why there is an implementation at all here if it's useless, rather than "properly" treating it as abstract with an error
I'd think an error would make more sense to have
why do you care it never reaches that point anyway lol
assuming that every structure should have its own _patch then IMO it should throw an error, not return the data
what User-Agent a bot uses when making a request to the API? I'm trying to access a resource with Postman and I get Access-Denied
i mean, when i put my browser's user agent i get denied
when i leave it empty it works
You might want to ask that in #697489244649816084 or #381887113391505410.
This channel is for discord.js
thanks!
Can we please revert https://github.com/discordjs/discord.js/pull/7759 ? This PR just sounds authoritarian as it is restricting users to one method of doing things where the other one is perfectly valid and not "confusing" at all unlike the PR originally claimed. One can send rest params and it will work and they can also send an array and it will also work, if anything the confusion is on the jsdocs, not the typings and that can be improved without needing this
This was discussed a lot before the PR even went up. We were frequently observing users in support passing arrays since theyre a naturally intuitive container object in Javascript and one that even beginners understand. So for that reason, it was important to support arrays.
As for why we no longer support rest parameters, supporting both forms of input has a performance impact - it becomes necessary to flatten or otherwise unwrap the array, if used, from the rest param argument. We are still looking at options to improve performance in that area though to see if supporting both can be viable
from the people that say the performance impact that validation has on builders is negligible and then say rest parameters are an issue that sounds quite hypocritical if I'm being honest
and honestly this diff from v13 to current v14 just looks ridiculous at this point
- embed.addField("test", "abc")
+ embed.addFields([{ name: "test", value: "abc" }])
There's also an argument to be made for an inconsistent interface if it accepts two different forms of input, but I know we've been over that on other topics and will probably disagree on it. Can I ask if/why you have a preference for rest params, or why its important to you to see both supported?
because 90% of the time I'm adding 1 field to my embed and being forced to put that 1 field in an array is just annoying and to me looks like it would impact performance more than using rest params would. For the situations where I'm adding more than 1 field it's still way more practical to pass the objects consecutively rather than throwing them into an array as that slows down development time by quite a lot (specially for someone using a portuguese keyboard like me where the [] are quite annoying to reach)
to me looks like it would impact performance more than using rest params would
Supporting rest params OR an array are exactly equivalent performance wise, since rest params become an array argument anyway. Supporting rest params AND an array is where the performance hit is introduced, since thats where we need to doargs.flat()orArray.isArray(args[0]) ? args[0] : argsor something.
I can't really comment on the portuguese keyboard thing since I don't use one, it doesn't take me any time at all to hit [] really
In fact a good IDE will put the ] in for you if you hit [ lol
why do you need to do .flat? Just grab the arguments with the rest operator in the function declaration and it makes it an array for you?
Not if we also support arrays
well obviously it does but still, we have to hit alt gr + 8 to get [ which isn't the handiest of combinations
...args, if receiving an array, is [[arg, arg, arg]] vs [arg, arg, arg] if rest
It becomes necessary to flatten, unwrap it, whatever
To be clear I have no preference either way on if we support both or not, I'd be fine with the performance hit of doing so. But I was in strong support of it not being only rest params because it was clearly unintuitive for users and yeah, the docs display for it sucked
you don't need to flatten (Array.flat) because if users pass an array it will always be the first index, you just need to check for Array.isArray(args[0])
Yeah that was the other option I listed
Array.isArray(args[0]) ? args[0] : args
Which I personally am fine with
I believe supporting both array and rest would be a good option, if the issue is with typings/docs it could be easily solved by adding a note or making jsdocs..well better
I feel this becomes an issue when multiple arrays are passed, feels like that could lead to some unexpected behaviors
and i feel with accepting only an array, the old singular addField may become requested to avoid having to wrap a single option like rodry mentioned
multiple arrays would never be passed
what
what if someone, for some reason, does .addFields([...], [...])
oh wait, misread some stuff, disregard that
thought we were having rest and array support and were transitioning to array
Yeah passing multiple arrays is just incorrect
meh, true
Although flat would work for that, we're certainly not extending support to a third set of rest-arrays or some shit
Yeah tbh my first response to embed.addFields([{ name: "test", value: "abc" }]) was something like "oh so what" but the more I look at it I kinda get it lol
yeah i thought it was going like how setAuthor/setFooter got deprecated
that's their problem lol
the syntactic complexity of this method has just gotten ridiculous with the removal of addField and now this, like honestly what are yall doing
isnt the only issue with supporting both rest and array is docs/typings? or is it performance issues?
Theres a small performance hit
when addField was removed, addFields was still just the rest parameter of objects, so it was arguably trivial to just wrap it up, but now with the array it just seems like it's a bit much for a single field
but is it really noticeable?
¯_(ツ)_/¯
yeah I dont see an issue with supporting both lol
i think if supporting both does happen then it might lead to the thing i mentioned with multiple arrays, since although it's not typed like that, users using javascript unfamiliar with the stuff here might just assume that, arrays are valid, rest is valid, why shouldn't rest of arrays be valid
might just be a moot point though
I don't understand why anyone would come to that conclusion
I mean, at first instinct you would either choose to pass one array or rest, only if you're doing it on purpose would you use a rest of arrays 🤷
also that already happens in v13 and I've never seen that level of stupidity yet
also why can't the users that pass an array simply add "..." to the start of their argument tree?
wouldn't that make everyone's life easier?
Sure but they can just add [] too
Except Portuguese people I learned today, sorry about that 😛
As an experienced developer, I agree, ...arr is easy, but it really isn't a well understood concept for most people
I believe it's even more annoying in spanish keyboards btw
Arguably, you could also use .forEach on the array. While it isn't as pretty, I believe it could be easily understood
back to singular methods? 😄
The perfomance diff is very minor, I did some tests and its below 1ms.
The average djs dev would not care lol
I just wanna make it clear that argument I made about supporting both was before I was shown a better solution to supporting both that didn't involve .flat
but imo, yes the argument to add singular methods back would be valid now if we were to stick with arrays only
The argument not to use builders at all because you can embed.fields = arr or embed.fields.push(...arr) or embed.fields = embed.fields.concat(arr) or embed.fields = [...embed.fields, ...arr]
JSON/JS objects superior, supports both arrays and rest
Regardless of arrays or no arrays, why do yall like to restrict users’ options so much? It’s not like you’re paying per method or line of code in the library so it should be about giving users alternatives
I mean... this is an interesting debate imo
bc for rest params it's the same method just with an 's'
Because we're not "paying" but people do spend time (and time is money) to maintain it
"alternatives" are inconsistency, maintenance overhead, in some cases code duplication
addField is a method that requires no maintenance after it’s implemented. It’s caused more maintenance overhead to deprecate, change syntax and then remove it than it would’ve to just… leave it alone
with all honesty, removing singular methods was uncalled for, it was perfectly fine as-is
Arrays vs rest is 1 line to support both and it’s over with, you don’t have to change that line ever again and you only need to care about whatever else the function does if anything
yeah im fine with supporting rest
Once again we’re back to creating problems to justify solutions that didn’t need to exist in the first place :/
well the original issue was forcing people to use rest over arrays and not allowing both
the solution is not using builders
like so many people were passing arrays in bc they didn't know what rest was and it wasn't expected
all these the builder changes would force someone to not use them and just use raw objects lmao
thats what I've been doing for quite some time
Weren’t both supported in v13?
I have also switched to json instead of builders
Builders are good if you want your input validated
UnsafeBuilders are, imo, pointless over objects
No, builders are good for type safety and code organization, I could not give one singular fuck about validation yet I use builders everywhere in my code
const embed: APIEmbed = {}
typesafe
just type it as api embed, yeah
We have object types
In fact builder validation is just stupid, the api validates it for ya
APIEmbed :)
yes
The point of client side validation is to avoid 400s responses
well, as the developer you should know what types of params you're passing to builders, so is validation really needed in that case?
And why are those bad?
in some places they were and some places they weren't embed fields accepted both but like action rows accepted rest only
There is a rate limit for requests resulting in a 4XX
well they'd start accumulating for the 1k errors/10 minutes thing, wouldn't they
Well that should’ve been the place to start fixing them, not do this clusterfuck of a mess with everything else
I assume if you get those errors you’d fix your code
And not let it sit there
the validation tells you to fix your code
is that not what it means
There isnt actually a type for the camelCase djs EmbedBuilder constructor param that I can see
So do 400s
But assuming we made one you could typesafe using that
but those you'd have to fix reactively, with validation you can fix them proactively
Type casting is never as type safe as passing an argument in a constructor or function
Thats not typecasting
No because your code would still be failing and your command would be broken
So you still have to fix that asap
builder validation fails at runtime, just like 400s
Exactly
reactively/proactively with regards to sending the request
How is it less safe, TS wont let you assign props to that object incorrectly
I’ve seen situations were TS kinda ignores type issues even though a variable is casted as a specific type
typescript fixes all issues with type safety and all that, purely validation is for runtime validation I believe
I havent
It’s never as bullet proof as a function arg
Builder validation throws before you make the request
Again, why does that matter
It’s an error you’d have to fix regardless
So having validation is the same
Doesn’t consume global rate limit nor the 4XX limit
ik it does, but builder validation isnt being fixed proactively
How big is that limit
because it happens at runtime
This argument is getting really off track
And, if you were following the chat, I said you wouldn’t let those errors accumulate so you’d fix your code before hitting limits
You praise the benefits of typesafety in TS but you dont praise the benefits of input validation
idk even know at this point, I'm just over builders in general. Note to future me: don't make builder PRs
lol
like im so done with all of that shit
remove builders altogether 
Revert back to v13 djs builders 
I don't even use builders so idk why I even get passionate talking about them
let alone make PRs for them
I have started using json when I saw the changes to builders in v14...v13 builders were better imo
code that sends requests without awaiting previous ones (the same kind of code that would fail the validation) could just send a significant amount of invalid requests before any one of them returns with an error
silent catches as well
Only if you’re sending thousands of reqs per second lol
Either way
doesn't seem that unlikely for me for that kind of erroneous code
It would be much easier to have what we had in v13 where builders organized data nicely, didn’t validate and supported all sorts of input for everyone’s likings
✨ objects ✨
just use typescript
not really the point of this conversation, but allow me to show this
but anyways make builders how you want them to be, I don't want to be involved with something I don't use anymore, it's tiring trying to be involved with them
why did we have builders in the first place again? to go with rest?
can't remember tbh
afaik you'd have to call toJSON() yourself all the time if that was the case
I don’t quite understand these results, the difference to the builder is only 2% ish but unsafe has 2m ops and the regular builder has 8k? Isn’t that much slower?
ah yes for my bot that needs to send 1.1 billion embeds per second
Thats 2% margin of error
Ahh
the percentage isnt the difference
In the sense that unsafe could have done 98% or 102% that many ops
thats not the point
Right
I will just put what I would want builders to be..
1 - either support both rest and array, or bring back singular methods
2 - stop removing functions that were working perfectly before
3 - and bring back v13 builders
Ok then ye builders are way worse than I thought wow
is that Zod or shapeshift though?
- Why either? Why not both of those
@discordjs/builders@0.14.0-dev.1650413406-585169f
it's using shapeshift
idk the reason behind removing singular methods, but if that was the case then rest should be supported alongside arrays
I'll do a PR that brings back the singular method and make it require a length=1 array 
Unions just create unnecessary complexity in the method just to bring it back to a single type or otherwise handle each case
The reason why builders exist is basically:
SlashCommandBuilders existed with input validation (and are good)
/builders now exists over there as a weird little thing with no other builder classes in it
discord.js has a bunch of builder classes in it so we move them to /builders and add the same sorts of validations
Those classes end up fairly different to what people are used to because the standards for builders (e.g. snake_case etc) don't align with discord.js
They have to be reimported back into discord.js to avoid code duplication
They have to be extended in discord.js in order to align with discord.js standards while still trying to minimize code duplications
Interestingly enough, if we fully aligned something like EmbedBuilder with SlashCommandBuilder, the interface would be embed.addField(field => field.setName('foo').setValue('bar'))
now if you left builders alone in djs that wouldnt be the case, as you moved them to builders, then moved them back to djs to allow camelcase...why all that hassle?
It was essentially a sort of repository design/architectural philosophy decision I guess
Not one I'm trying to defend or justify, only explain
¯\_(ツ)_/¯
just from personal experience, these builders changes werent needed and moved me to use objects instead so... yeah ig these decisions werent so good imo
If you moved to objects, they were good enough
Opinion time:
- No to the first half, sure idc about the second one
- We removed no functionality
- No
Like the amount of headaches that builders have caused over something that's meant to help you is getting tiring :p
If you don't care about the benefits of validation or you do validation yourself, use unsafe builders or objects. Otherwise use validated builders
Builders are meant to help you not send invalid requests to Discord, which depending on your bot throughput and amount of invalid data sent could outright ban you for at least an hour from doing anything with the api
If you don't care about the benefits of validation or you do validation yourself, use unsafe builders or objects
... unless if you want to use the features that were added in the extended builders in djs, if so you'll have to use objects as the "unsafe" builders arent being extended in djs
For the 90% of users that's fine and probably much better than getting some obscure error from discord (which I've seen plenty of people not be able to read)
Also the only "feature" the extended builders in d.js have is allowing you to do new Builder({ camelCaseInsteadOfSnakeCase: true })
Which affects only component builders currently
(ala customId and the gang)
embed setColor accepts hex strings
button setEmoji accepts everything that parseEmoji does
(which is something that should be used very sparingly as it does no validation)
Wdym it does no validation?
values passed in the constructor arent validated
What's the use case for hex strings? It's the same as the number variant, only replacing 0x with a hashtag
i dont use builders, i was just pointing out the inconsistency
For setEmoji we can probably add shortcuts/overloads for it but there's no inconsistency as builders are working with raw api data
but since its available on the regular EmbedBuilder, i assume there are valid use cases
wdym "there's no inconsistency", i just showed you inconsistencies between the "unsafe" and "safe" builders exported in discord.js
Unsafe builders are meant to be bare metal, they're to be used only by very advanced/experienced developers who know what they're doing, not by the regular users.
And the target public they have doesn't whine about little things such as casing or easily fixable abstractions.
👍
Creature comfort shortcuts, like setEmoji accepting a string, not just an object, fit more in djs than builders. At their core builders are meant to work with raw api data in a nicer, chainable way (see application command builders), and also bring in validation so the API limit isn't drained from possibly invalid data sent.
It was mentioned in the pr that added it, values returned by APIs
API doesn't return hex values for anything
The only time it did was for the user accent color and that was shortly after changed to a number
Is it best practice to just use objects instead of the e.g addFields function?
it's easier to use embed builders rather than json
but what's considered best practice
embed builder
It really depends on you. Some prefer to use JSON objects because they are faster, easier to adapt to new features and comfortable if you want to statically send an embed (so you already have all the properties before); others prefer to use Builders because they allow you to validate all properties before sending the embed and are more convenient for example to add fields or do something else dynamically
JSON. nothing about builders is more convenient or easier than a normal object
This is not the channel for this discussion, and if the question is for best practices than the tool that provided validation would be the one to recommend, personal biases aside
So what's the takeaway from yesterdays convo about builders and rest vs arrays / singular methods / whatever the hell we talked about here?
can we bring back both rest and arrays and singular methods?
I dont think that was the takeaway
We could bring back rest or singular methods. If we bring back rest, addFields wont require an array and operates as a single method also
If we dont bring back rest, singular methods have a more distinct purpose that isn't being duplicated by another method
I like the idea where we don’t do either
You also like the idea of breaking every single thing in the library for the sake of it so why bother right
You're the one using an in dev version of WIP software
why does it matter if it's WIP or not? You're making these poor decisions consciously and don't seem to wanna go back on most of them
There have been very few if any poor decisions, and most have changed since. And it does matter because this isn't the final product so things are bound to change
it would make sense to say that if you had any plans to change these things, but it doesn't seem like you do
It's simple, it all comes down to iterative design and development, we can't make perfection in one go, also should be expected to be unstable considering /builders is literally v0 at the moment
This is not a constructive conversation, rather just accusations and insults towards the maintainers of the library.
@outer raven I agree with you, don't worry 👍
but i think these changes doesn't change anything for users you can easily change rest parameters to array
It’s not about the difficulty of doing one over the other, it’s about things like this
tf
are they gonna kill off v13 like they said with v12 but never did
i have no idea what you are trying to say with that.
we do not provide support for older versions some time after a stable version is released (if you still want to use v12, feel free, but don't come here for support with it).
we said that v12 will stop working with some new features discord releases (messages in voice channels, to name one) or (ultimately) if discord decommissions the API version used in older versions.
discord continuously pushing that deadline back has nothing to do with us.
old versions (v12 and earlier) will not receive any updates, new features or bug fixes and will break if certain unforeseen things are introduced (messages in voice channels, to name one).
thats what i heard anyway lmao
like oh yea v12 is gonna be dead in a few months!1!!1
Not anymore. It's been extended
That being said, move to v13 :)
cool, so if you know this doesn't need to be discussed - so why even bring it here in the first place
yes your right rest parameters looks better
It's not a matter of which code looks better, but which code is the most expected for end users
Most people expect arrays when seeing addFields, while almost nobody expects rest params to be used there, only very advanced users would
well know i do bc im here
I've gotten used to rest params and expected them since I started working with djs because if we're adding fields, I expect to pass each field individually to the method
it pains me that just about all of those conversations start with insults or "there's no reason to do X", constructive criticism has become so incredibly rare
even in this instance you're being told the new interface for the method is meant to be more intuitive to people new to the library or language in general and your response is "but I've been using the library since the time when it wasn't this way and as such it feels less intuitive to me" which just about boils down to "change bad"
It's the same with every new release. People choose to collectively hate it, they get convinced to change, realise that the newly added implementations aren't utter horseshit and actually contribute to the library's experience, and make that release their new basis for future criticism to change
no I never said "change bad", in fact, change is often good when it has reasoning behind this other than pure personal preference. They are saying arrays are more intuitive to new people, and I simply argued that, when I was new, rest parameters were more intuitive and explained why.
Change is more than welcome if it benefits people in the long run. If it's changing for the sake of changing it's stupid and should be avoided. The library should broaden people's choices and not limit them to what the maintainers like
Maybe you could create a pr
I could but I don’t know if it’d be worth it because the maintainers outright ignore the PRs they don’t like and leave them sitting there forever
So if we learned anything from this convo is that the same would happen to that PR if I made it
Shocker, maintainers have final word on what they want in the library. That's never happened before.
the shocker here is them not caring about what the community wants and going against it
Oh don’t worry, we do care.
Just the bigger picture and not so much a vocal minority
I agree, change for no reason is not intuitive, like how many times have the constructors been changed for no reason, really annoying to have to rewrite all your code just cuz of a stupid pointless change
aren't there only like 4 constructors that you're supposed to use
I stopped arguing about this a long time ago
Development is iterative
If you use a -dev version, no guarantees youll have to change all the way until things land in stable
and if we can't land on a good compromise, and change things back and forth 3 times, youll have to suffer and sit it out
At the end of the day, 90% of the user base won't care though, because they don't get to have to change 4-5 times, they have to change 1 time, from v13 to v14
Or just pin to a commit if you're using dev for a feature
JFYI, nothing stops you from making your own class extending our builders that take spread arguments, Rodry. Something as trivial as addFields(...fields: Parameters<EmbedBuilder['addFields']>): this doesn't need any extra maintenance.
is Collector.endReason broken?
import { Collector } from 'discord.js';
const collector = new Collector({}, {
filter () {
return true;
}
});
setTimeout(() => collector.emit('collect', { hi: 'there' }), 1);
for await (const [i] of collector) {
collector.stop('end reason');
}
console.log('end reason is:', collector.endReason); // undefined
doesn't exist on the base collector class ig, it does on other collectors
having issues with InteractionCollector too, it's documented too, just doesn't work
https://discord.js.org/#/docs/discord.js/stable/class/Collector?scrollTo=endReason - the stop function doesn't seem to do anything with reason other than pass it to the end event.
do these just not support custom reasons
looking at the code i don't see this, nor do i see MessageCollector using custom reason
they're supposed to but they only work for the end event
i've brought up endReason being kinda... arbitrary before and gotten not any response
#archive-library-discussion message
okay so it's just broken, ill see if i can make a pr to fix it
#7833 in discordjs/discord.js by KhafraDev opened <t:1650747038:R> (review required)
fix: endReason not being properly set in base Collector
📥 npm i KhafraDev/discord.js#fix-endReason
@copper laurel on https://github.com/discordjs/discord.js/pull/7812 why did you add optional chaining instead of simply changing it to this.id? Wouldn't that be safer and achieve the same result?
But then it wouldn't be passing the message id at all when it is available
And then what would be the point of coalescing it later?
if you replace this.message.interaction.id with this.id you don't need that and you achieve the same result since this is always an interaction
idk why that workaround is there but it looks useless
The interaction that sent a message is not the same interaction as this quite often though
so is this meant to be like if you execute a command then press a button on it and update the button response it returns an interaction response with the original command?
doesn't make sense to me
and you can use buttons on messages
It passes both though
The first parameter is this, why would it be passed twice
yeah but why
I didn't look into the functionality, I fixed a bug
the class does that anyway
Yes I know
if id is null it uses the interaction ID
if the optional message id isn't passed
Which certainly suggests there a valid reason for it to be passed
what could be the use case for wanting the id of the command ran originally in the return value
also that description in the docs is misleading
I don't know I didn't build those classes. I fixed a bug and have no interest in arguing about it
but i wanna know if this is a bug worth fixing or not
Well the library isn't broken now. Seems worth it to me
what kinda answer is that
One that comes from frustration that I seem to have to justify why I made a simple change to prevent the library from crashing. I was not looking to redefine or change any functionality. I didn't design that functionality. I just prevented a crash which certainly seemed "worth fixing" then, and still seems worth it now
all i asked was if there was another bug here jeez
rip
⚰️
why does discord.js still use node-fetch v2.6.6 and not 2.6.7
because 2.6.7 was just a security fix for something that discord.js wasn't even effected by
i.e. the question you should be asking "why should discord.js update to 2.6.7?"
and the answer is "there is no reason"
discord.js v13.6.0 released on 13/01/2022
node-fetch v2.6.7 released on 16/01/2022
but dependabot is too worried for me
unlucky
Your package manager will automatically install 2.6.7 also u can add it in resolution
yarn didn't did that
is it intended that GuildExplicitContentFilter and GuildDefaultMessageNotifications aren't exported? seems like an oversight
also
this should be ActionRowData right?
uh which branch of the docs are you looking at?
main
also this in SelectMenuComponentOptionData
In that case yeah it should be ActionRowData
We’re waiting on -types website to deploy so we can link it
in the types, SelectMenuComponentOptionData.emoji is ComponentEmojiResolvable, which is APIMessageComponentEmoji | string, but looks like it doesnt actually handle strings in v14?
In discord.js it does in builders it doesn’t
strings worked in v13 but in v14 looks like it passes directly to Discord instead of serializing to the object
i am not importing builders anywhere in my code
Hmmm it should work, it was added
this is in an object being passed directly to interaction.reply
Oh you’re using the json not the builder
Iirc json doesn’t take emojis directly as strings anymore
d.js passes it to a builder internally ```js
const components = this.options.components?.map(c => (isJSONEncodable(c) ? c : new ActionRowBuilder(c)).toJSON());
Getting a 405 error on the permissions set endpoint saying "Method not allowed", how do we set permissions now? Does djs need to update?
working on it, you cannot set permissions without an oauth2 bearer token
you can't you need to set permissions in server settings
Well but my bot was setting permissions 2 hours ago and now I need to change everything because Discord decided it would be nice to put everyone on a crash loop?
@copper laurel Discord didn't deprecate the endpoints, they removed them
that's not how that works, if they removed it, you'd get a 404
Rephrased to "removed access to"
they removed access to it, thus the "Method not allowed" error
that is correct yes
Yeah not really a deprecation either in fairness
Since its an immediate breaking change
I thought Discord was against these kinds of immediate changes but god was this update dropped awfully
Their keep postponing things i dont like it
They say that every time they do this and apologise and it won't happen again until the next time it totally does
We literally warned them against doing this too
Angry
Disabled the batch editing endpoint (PUT /applications/{application.id}/guilds/{guild.id}/commands/permissions).
I see that it is already being discussed, but why would you do that.
So, there's no proper way for bots to edit command permissions (yet), correct?
Just saw #769862166131245066, yikes ig
well, there was
also, the single edit is still there, but it requires a bearer token now.
I used it before to make an interactive permission menu, but, yeah, it's useless now.
is stable branch still receiving updates?
it will once a new update gets released (v14)
13.7 should be the next stable version actually iiuc
it should but it wont go to the stable branch, i guess it would be in the 13.x branch
Nothing ever "goes into" stable unless youre Discord releasing a breaking permissions update
There will be a new v13 version that becomes the "stable" release when it's ready
i meant getting something merged into the literal stable branch
We'll likely also have a stable v13.7 and a stable v14.0 at some point
from main
There's different ways to release - you could merge the v13 branch into stable, delete the stable branch and re-tag/branch it off v13
o
@ruby terrace does this mean your PR will add support for user tokens or what exactly is this about?
bearer tokens, as it says, user tokens are not bearer tokens
they are ?
bots use bot tokens, users use bearer tokens
users use tokens, no prefix
Then what’s a bearer token
I think a bot token on behalf of a user
You basically give the bot permissions with your user account, which must be in the server and have permissions etc.
this is absolutely not a discussion for here, tbh
True, sorry.
oauth2 tokens
Why would djs support that now if it doesn’t anywhere else
Maybe they want to add new things to the library but idk
because there isn't much to "support" in oauth land regardless - and what there is is generally encouraged to be separate from your actual bot (e.g. dashboards with discord auth) so there's no need. in this case those are endpoints that require bearer tokens that you might actually find yourself wanting to use within the bot itself.
Such as add guild member
Will there be guides on how to get such token and how to update permissions through the bot?
There's alr a section in the guide for obtaining an OAuth token
i think (and hope) that devs wanting to do settings for peoples permissions is so much of an edge case that it's not worth it to explain the entire payload in all its intricacies and the above OAuth section is enough
will ofc. have to explain member and dm defaults, once those are implemented and released in the library vs. the permission endpoint
my bot is only in 1 guild so it'd be nice if I could set the permissions on that guild automatically and I currently don't know how to get that token so that's why im asking
it's an edge case tho ik that
https://discordjs.guide/oauth2/ should be sufficient for that
alright, thanks
apparently djs can throw this type of error? I've never seen this before and it doesn't look intentional, does anyone know what happened here?
internet had a stroke
Not related to djs either, its just that when we tried a request, your internet said
(you can read up what ECONNRESET means online)
hmmm weird cuz this was on a hosted server but alright, I thought djs wasnt meant to throw raw node-fetch errors but thats fine then
Isn't this description of the event slightly misleading, since when partials are enabled even if the message isn't cached before the Action, a partial is cached in it's place
Saying it this way doesn't make this completely clear
fetch doesn't throw errors on http error codes, only on network errors
Generally speaking the documentation of changes in behavior due to enabling partials is lacking in Client events
Or am I missing something 
yea for TCP errors there's honestly little purpose to throw custom errors - you can't really give any additional information
this goes for the gateway as well
nothing is gonna be more informative than "econnreset" coming straight from your OS
What does a malformed request look like? https://github.com/discordjs/discord.js/blob/2fe1c6c3598e1c704496ceff1738b6046deed631/packages/rest/__tests__/RequestHandler.test.ts#L523
seems like not even the code knows
It's meant to test extreme cases
I added the comments in a commit cuz it didn't really make sense.
would u happen to have an example of an "extreme case"? a 601 status code doesn't exist so it's just testing something nonsensical atm
probably just that, if non-sensical cases are handled "correctly"
partially a bug in undici that I accidentally caused, but the test just seems pointless. If discord ever sends a 601 status code, they are doing something very, very wrong
Or could be April Fools
I noticed that the README mentions zlib-sync and erlpack as optional dependencies, but neither discord.js itself nor any of its dependencies have them as optional peer dependencies. Should they be added to the package.json?
No
Why not?
Because npm v7 pulled a funni and tries to install peer deps
I've been using yarn pretty exclusively so I guess I wouldn't know. Still, I think it would be helpful to mention what version(s) are accepted
Which makes them behave the exact same as optionalDependencies
Any version, tbh
If there was incompatibility with a certain version, we would probably add code to handle it, but they never change
I just saw that nothing in my lockfile mentioned them and I almost just assumed they were unused
I suppose one thing you could do, something I've seen other libraries do, is just add them to peerDependenciesMeta but not peerDependencies itself
so like
"peerDependenciesMeta": {
"erlpack": {
"optional": true
},
"zlib-sync": {
"optional": true
}
}
typescript-eslint does this for its dependency on typescript, for example: https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/package.json#L69
could https://github.com/discordjs/discord.js/pull/7833 be backported to v13 too?
doesn't work with npm still
Why not? I just tested it with npm 6, 7, and 8, and it seemed to work just fine in all of them
well I tested it out with a package of my own that has
"peerDependencies": {
"typescript": ">=3.6.2"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
and installing just that and nothing else, with npm 6, 7, or 8, did not install typescript. I fail to see why this situation is any different
what would be the benefit of adding that then
@dawn merlin I'm confused, channel flags have nothing to do with permissions v2
the pinned flag is for forums
Oh lol my bad I knew it was something newer I’ll fix that
They do, also this is not the channel for support it's #djs-help-v14, this channel is only for developing the library
I feel like it's some sort of bug now, because if i type 5 in the value of the key type, it doesn't give any type errors but if i use the enumResolvers to do the same thing it doesn't work
client.application?.commands.create({
name: 'ping',
description: 'tells The ping of the bot',
options: [{
name: 'ephemeral',
required: false,
description: 'Should the message be only visible to you or no?',
type: EnumResolvers.resolveApplicationCommandOptionType('BOOLEAN'),
}]
})
at that point it's just easier to use the actual type than enum resolvers, it even tells you its name
Its because theres a version mismatch currently probably
between builders and djs
@tacit crypt here’s an argument for supporting rest params if you want: Array.prototype.push takes rest params as input so people might expect these functions to do the same, since fields, options, etc are arrays of objects, and they can’t modify the arrays directly because they’re not exposed
Actually i really like the enum resolvers (if they actually work), i would like 1 import rather than like 10 imports just to basically type numbers and strings
Testing it on my end it looks like an issue with the types in general. It's caused by the fact that enum resolvers don't give specific enum type. When ts receives the type it gets ApplicationCommandOptionType but it wants ApplicationCommandOptionType.X. The only workaround I can think of is to cast the resolved type to the type you want, but at that point you're just better off importing the enums 
We could use mapped types to make the enum resolvers more specific, but not sure how feasible it is.
unless you're doing something weird, you only need to import discord-api-types/v10. Enum resolvers are just entirely useless and i don't really understand the point of having them.
I meant 10 different enums from one import actually like ComponentType,
ApplicationCommandOptionType and many more
Yeah. If anyone can write a long EnumResolvers.... then why can't they use enum.
Well still that will be better then writing like
EnumResolvers.resolveApplicationCommandOptionsType('BOOLEAN')
Which is longer then using enum
I understood a little after I posted. It's entirely a nitpick since enumresolvers still have you writing more for the same functionality. They are entirely useless;
- types aren't correct
- don't make transitioning from v13 easier
- are longer than discord-api-types' imports
- don't benefit js users... they'll either hardcode values in or use discord-api-types too
I really don't see the purpose of having them in the lib 🤷♂️ Honestly I think it'd be really great just to remove them entirely before they land in v14
That's a good point, but they can be useful in some scenarios to shorten the code. For example, if we're writing a component-making command and the arguments in that command need to know which type of component we need to make, to resolve what argument they've given, we can use enumResolvers.
I have that in my bot (a Component factory), on a v14 branch, using only discord-api-types.
Open source?
Nvm
import {
ComponentType,
ButtonStyle,
type ButtonOptions,
type APIButtonComponent
} from 'discord-api-types/v10'
const Buttons = {
// ...
deny (label = 'deny', id = 'deny', options: ButtonOptions = {}): APIButtonComponent {
return {
type: ComponentType.Button,
style: ButtonStyle.Danger,
custom_id: id,
label,
...options
}
},
}
is the general gist; creates a danger button with a label & id (and optionally other parts). This codebase is from v12 but in v14 style so I would probably change it to 1 object parameter instead if I could re-do it
Yeah I have something similar... Honestly enum resolvers are a bit more confusing and don't seem to help anyone. Although I don't see why they should be removed, if someone (who uses js probably, not ts) is more familiar with them instead that enums, just let them use those resolvers
theres no need for anyone to become accustomed to them because they only exist in v14. now's the perfect opportunity to remove them before it's a semver major change
Hey guys, I see there’s permissions on commands, is there any update on that on discordjs?
Thanks
do v14 types still need fixing?
as in? what specifically?
If you've found any bugs then yeah
this doesn't work, did I make a mistake?
components: [
new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setLabel("Send Embed")
.setCustomId("send_embed")
)
]
Yes
Use #djs-in-dev-version also addX takes an array
can someone tell me why there's ban and kick method on GuildMemberManager but theres no timeout method
please
there is
<guildmember>.timeout()
There's a ban method because there's a ban route
There's a kick method because there's a kick route
There's no timeout method because there's no timeout route. It's in the edit route
Ok
But there is 
it isn't its own route
Veri nice banner and profile picture i like it
you could add timeout method to GuildMemberManager but ill do it myself because you probably wont
you could just use the existing edit method
ill think about it and let you know
you don't need to let me know your own decision lol
Hi there
This is somewhat trivial, but have you thought of adding yourself on https://github.com/discord/discord-open-source ? Entries there are used to populate the list at https://discord.com/open-source
At this time, we are accepting communities which meet the following criteria:
Your community is not Discord-focused (for example, Discord bots or modifications are not accepted).
Your community has at least 1,000 members, or the GitHub repo has at least 1,000 stars.
Your community adheres to the Discord community guidelines.
im pretty sure a dapi wrapper counts as discord focused
Ahh alright then, my bad
why is djs using experimental node features? Shouldn't we wait for them to come out in stable versions of node?
I think that specific one is stable in a later Node.js version. Nothing was changed between the phase so it should be okay
is there anything holding back https://github.com/discordjs/discord.js/pull/7747 anymore?
or like is there anything the maintainers have talked about in private that would hold it up
No specific internal discussions thats Im aware of, probably just needs reviews
Is there some kind of roadmap to the ts rewrite plans?
since there's only one pr left in the 13.7 milestone which has been sitting there for two months, wouldn't it be better if d.js 13.7 was released without that pr and then include it in a 13.7.1 release?
there are a lot of new features people are waiting for like modals
milestones are not dated and progress is not necessarily indicative of a release
this site is lying
oh
it's not lying, you just misinterpret milestones that have no dates
ws you mean?
wasnt 13.7 supposed to have attachment option type modals and a few backports and thats it
No one said that
You can say backports weren't initially planned but plans change and they are here
The milestones mean nothing, i can legit add prs to it and they'll be in the milestones. Again plans change and before that pr gets merged more prs can be made, nothing is really certain, looking at a constantly changing list of prs doesn't tell you anything about when the thing will be released
hm makes sense
hello, why in the stable version of discord.js the StaticImageURLOptions part has more dimensions than in the main? example: 16, 32, 56, 64, 96, 128, 256, 300, 512, 600, 1024, 2048, 4096.
the official API spec https://discord.com/developers/docs/reference#image-formatting documents it as
The returned size can be changed by appending a querystring of ?size=desired_size to the URL. Image size can be any power of two between 16 and 4096.
which is16, 32, 64, 128, 256, 512, 1024, 2048, 4096https://oeis.org/A000079
thank you, information
was the oeis link really necessary lol
yes, oeis is nice and more people should know about it 
is there any reason type Snowflake is defined as string rather than, say, `${bigint}`? I realize it would be semver-major to change but I'm curious if there's any motivation beyond supporting TypeScript <4.1
It actually was ${bigint} for a bit, but there's was a TS bug that caused it to be reverted iirc, it was also really annoying to deal with in most cases
huh, good to know
thanks
https://github.com/discordjs/discord.js/runs/6399925239?check_suite_focus=true why this test is failing?
Not a bug, the community just rioted against it, so we reverted it
Rioted is a strong word but yes. It was that before, many people complained about it because it made code require far more casts so we reverted it
Honestly, a lot of things (like, the vast majority of things) didn't require cast at all. It's more an issue with third-party libraries that didn't use the type (which we cannot control at all), and with the users' own code being typed to emit strings instead of Snowflake's
Being back stringified big integers :c
@golden mortar not sure if you know more but
I can't seem to get proxying via undici to work, except for one method
lets presume this is my file
const process = require('node:process');
const { GatewayIntentBits } = require('discord-api-types/v10');
const { token, prefix, owner } = require('./auth.js');
const { Client } = require('../src');
// eslint-disable-next-line no-console
const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
first I tried the obvious way doing
const process = require('node:process');
const { GatewayIntentBits } = require('discord-api-types/v10');
const { setGlobalDispatcher, ProxyAgent } = require('undici');
const { token, prefix, owner } = require('./auth.js');
const { Client } = require('../src');
setGlobalDispatcher(new ProxyAgent('http://localhost:3000'));
// eslint-disable-next-line no-console
const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
which didn't work
so I tried doing
const process = require('node:process');
const { GatewayIntentBits } = require('discord-api-types/v10');
const { ProxyAgent } = require('undici');
const { token, prefix, owner } = require('./auth.js');
const { Client } = require('../src');
// eslint-disable-next-line no-console
const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
rest: {
agent: new ProxyAgent('http://localhost:3000')
}
});
which also didn't work
so I went all the way down and did
const process = require('node:process');
const { GatewayIntentBits } = require('discord-api-types/v10');
const { ProxyAgent } = require('undici');
const { token, prefix, owner } = require('./auth.js');
const { Client } = require('../src');
// eslint-disable-next-line no-console
const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
client.rest.setAgent(new ProxyAgent('http://localhost:3000'));
and this seems to be the only way it works
I can't really explain why though, none of the things should be instantiated on import
and only on client creation
the first way (setting global dispatcher) is probably fixed in the newest undici, 2nd way is probably a bug, glad it worked in some capacity tho
i think the 2nd way should work too so ill try fixing it

newest undici means you need to update?
that's just a guess tbf, in 5.2.0 the setGlobalDispatcher was made completely global. before having 2 versions of undici (ie. using node's & undici dep somewhere else) wouldn't both work when you set a global agent
ah
anyways, setting agent with RESTOptions should be fixed now
The fix for the 2nd might actually collide with the fix for the first global dispatcher
How so? If no agent is provided per request and no agent is provided in the current RESTManager, it'll default to undefined. Undici will auto set it to the globalDispatcher then
it's not possible to test these changes either with jest because undici's mock system requires a global dispatcher to work lol
imo setting a global dispatcher should be discouraged especially since it can cause issues and unexpected behavior (ie. having node's fetch proxied because you set a global dispatcher in undici)
you can easily test it with a tiny bot I put above
just put in some fake localhost
the manager will destroy and the process exit
yeah true, I guess we don't need it
having the options work is good enough imo
thanks for fixing that
this means we can now proxy discords requests to https://github.com/twilight-rs/http-proxy
and have shared ratelimiting
👍
and now setGlobalDispatcher works, what a weird issue. Once I updated discord.js' undici it worked instantly
I still can't seem to get this to work 🤔
'use strict';
const process = require('node:process');
const { GatewayIntentBits } = require('discord-api-types/v10');
const { setGlobalDispatcher, ProxyAgent } = require('undici');
const { token, prefix, owner } = require('./auth.js');
const { Client } = require('../src');
setGlobalDispatcher(new ProxyAgent('http://localhost:3000'));
// eslint-disable-next-line no-console
const log = (...args) => console.log(process.uptime().toFixed(3), ...args);
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
it connects fine
instead of crashing, like it does when I set the agent in the client rest options
undici is on 5.2.0 on both
also reinstalled with yarn
(node:20284) ExperimentalWarning: The Fetch API is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
Error: connect ECONNREFUSED ::1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1195:16) {
errno: -4078,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '::1',
port: 3000
}
Node.js v18.0.0
it throws for me 😕
const { setGlobalDispatcher, ProxyAgent } = require('undici');
const { Client, GatewayIntentBits } = require('./packages/discord.js/src');
setGlobalDispatcher(new ProxyAgent('http://localhost:3000'));
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent],
});
weird
I guess ill take your word for it
are you using client.login? I omitted it from my example
Yeah
I may require undici below the client
But I doubt that’s it
Sec I’ll try your stuff
Yeah no I can't get it to work
lmao, I guess ill just take your word for it
its not like i need this use case
if it works it works
waw, didn't even cross my mind this would be possible so soon
wait, you still need a way to skip djs' ratelimiting right?
if it returns no headers, theres no issue
ahhh right, if it strips them its cool already
wow
end of an era
I got the idea because I wanted to do some rest requests inside a worker with /rest, but then I thought I couldn't because the ratelimit isnt shared
but this way I can proxy inside the worker and on the main bot to the http-proxy
and have it shared
yea I know the feeling, this is super nice
and undici makes this really painless
while node-fetch its super painful and needs another dep
lol
technically this was possible before with node-fetch with a hacky agent yea
yeah, node-http-proxy-agent or something
I looked into it before and noped out lol
hm, couldn't there have also been a client option to overwrite the API domain? (unless there is one already)
yes but this is nicer
yea f sure
this is the proper way
exciting
now to wait for a gateway pkg from you all :^)

lmao I just realized
that also solves the sharding issue have where they hit 409 on the /bot endpoint
can just tell them to install a proxy now
bless
Is there a reason why this can't be supported on api messages?
an APIMessage is a raw object from the api
Ok but if djs is going to serve these objects, why not wrap it with these extra methods?
Like the one I showed, obviously not all of them can be reflected but some of them definitely can be.
lots of people don't know this but you can actually import InteractionCollector from discord.js and create your own collector. So much easier imo
in v14 if you don't have to fetch the reply if you just want to use a collector
Ah, cheers then. Probably should have checked that lol
EmbedBuilder from the builder isn't assignable in message send options. Will there any 13.7.1 release if so I can create a pr
you should probably be using MessageEmbed in v13 for now
I want the builder one. Bcz I've a embed cmd where I need validation of user's input
well maybe I'm can just cast it as most of the ppl won't use new builder with v13
does it not work if you use .toJSON() on it?
hm yeah I can use toJSON
@wild flax looks like you forgot to announce 13.7 at #announcements
Is it possible to move the features part of the changelog to the top? The changelog for 13.7 is so big that dependabot cuts out most of the features so you can’t read it all
You can just open the changelog, Dependabot also includes a link to the full changelog
can someone just reimplement https://github.com/discordjs/discord.js/pull/7918 with a correct commit subject and without so many fuckups, i am sick and its taken me 3 commits so far to change 1 line of code. thanks
the amount of commits in your pull request doesn't matter, they squash them when merging
ik but the first commit msg isnt even right at this point, im just disoriented and a dipshit today and not ready to follow up on it
there's a new git option to use the pr title when squashing so it shouldn't matter
and if they really cared about the first commit msg, they can also just change it themselves when merging
You can literally edit what the commit message will be when using squash & merge
I'm remaking your pr with a test so that issue doesn't happen in the future
https://github.com/discordjs/discord.js/pull/7919/
for reference:
you do realize thats not practical right
dependabot shows the change log so you dont have to open a new tab
so the libraries should make their changelogs properly
tysm
does anyone know why /rest imports dom types? https://github.com/discordjs/discord.js/blob/d522320aa400ee6ab8f5ff2d927cd361ee98cab1/packages/rest/src/index.ts#L2
I'm spitballing here, but I wanna say it had something to do with the form data types? Pretty sure undici fixes that though
I made a pr to remove them 🤷♂️
Does it compile without it errors?
it did on my side, the ci failed (just needed to import performance though, I think)
ci failed because of the other types issue 😐
is there any reason why i'm not getting these errors on my side?
Are you compiling or running the tests?
Also it looks like it’s from djs not rest
I typically run yarn run format, yarn run lint, and then yarn run test in the root directory, so it should be catching those errors(?)
Gotta build too
what a hell in changelog? backport backport backport...
I mean it's unreadable in changelog. I wanted to know quickly what are the changes, but I should click on 30 links and read what changed
That's 7 links, not 30.
didn't know about it, thx
Tip: you can also middle click links to open them in a new tab, makes opening them a lot faster 👀
not on phone
but yeah someone thought it would be a good idea to make 7 PRs all with the same name
the issue is that its unreadable and not practical
of course
why wasn't v13.7.0 not announced? It was released on github and npm but never here.
Or Ctrl + Left Click
I'm using ctrl+shift+left click
Yeah I noticed too late when merging and GitHub didn’t have the option yet to default squashing to the PR title instead it picked the first commit message
There’s no way to change this except to manually change it and force push, which is not an option either
So you’ll have to live with the occasional mistakes like that
the site libray is not working
im clicking on stuff and nothing happens
What's that?
when i click on those nothing happens
#archive-djs-help-v13 message I found an inconsistency between the docs and typedef
The typings should not include a number there. It will always be a string
to be honest, it's not good idea when you don't announce a new version/update of a library, like why would you leave people use outdated releases when the new update has been released, kinda frustrating, and yeah, i'm not here to argue about it, just sharing my opinion on how this is a bad idea
It doesn't matter at all if people are still using a previous release
It will continue to work just like it did the day before the release
I don't closely follow the releases of most libraries I use - I build and deploy with a specific version that I know works for the code I wrote
that why 13.7.0 wasn't announced in #announcements, well good for you then ig
I can PR a fix, should it be to the v13 branch or main?
Main doesn't use strings anymore, so that won't be a problem there. It should be the v13 branch, but I am currently unsure if we are making a new release for the version 13 line
okay, i won't pr then
sure it can stay like that in the commit history, but the changelog needs to be edited
"needs" is a bit of a strong word here
https://discord.js.org/#/docs/builders/main/class/SlashCommandBooleanOption?scrollTo=runRequiredValidations
Docs is showing protected methods as public methods
I’m pretty sure docs doesn’t know how to represent protected methods
Should all protected methods be hidden, or a badge stating they're protected?
Could probably tweak something about that
Imo they should display as private since protected methods are private with extra steps
They are most certainly not that. Protected method can be accessed by the class and whoever inherits the class. Privates cam be accessed only by the class that defines them
Imo don't hide (as it's not private) just add a badge (so people will know it's protected)
but it can't be accessed by instances of the class can it
i mean even privates can, just that TS will scream unless you use [] accessing
hi guys
well it can but it's not supposed to, so it shouldn't show up in the docs because odds are the average user won't need that
hello hello, I spoke a bit with @ruby terrace and was very intrigued by the idea of a @discordjs/proxy after the convo I had with crawl re twilight here a few days ago (now that undici has made it trivially easy to proxy with /rest)
#7925 in discordjs/discord.js by didinele created <t:1652615263:R> (review required)
feat: @discordjs/proxy
📥 npm i didinele/discord.js#feat/proxy
I've started up a basic PR and would appreciate some general guidance as I work through it 
mostly I think what I'm interested in the most is what would be considered in/out of scope
twilight exposes metrics among other things, but that seems like something we wouldn't add to this
e.g. right now the only public function I have in mind is proxyRequests(token: string) => (req: T, res: T) => Awaitable<void> (where T are the proper types)
takes in a token - returns a middleware handler that passes things to a REST instance that makes use of that token
working on a tiny implementation, my main concern so far is being unable to correctly forward headers and the status code without listening to the response event which gives me access to a Dispatcher.ResponseData - but that's a crazy hack
this can sorta be worked around by manually re-computing the status code and content-type, but it's one heck of a compromise
ideally there'd be a method on REST that can return a raw response, hm
why not just return your own Agent (maybe extending ProxyAgent) where you can get all of that info?
hmm
could you exemplify
I can't really imagine how that'd work
oh, I think I get what you mean. I could intercept basically the entire request with a simple Agent huh
I could do that to copy over headers, status code n such, and then the body is obtained as it is right now
I'll def look into this, ty for the idea!
it's less hacky than the alternatives thats for sure 
yeahhh making an agent seems quite hacky as well 😬
@tacit crypt think you could give me some insight here if you're around?
the tl;dr is I somehow need to get a hold of the raw HTTP response that passes through REST at some point - since REST#request will only give me the body.
there's... 3 main options
a) I listen to the response event and wait for it to emit - scuffed and unsure how I could make it accurate
b) I hook an agent/dispatcher into the request that extracts the data for me - not... that bad I guess, it's just ugly and means the user can't use their own agent which is arguably an odd limitation
c) I open a PR that restructures REST a bit. the idea would be to have a method that returns the raw Response object while the existing ones (request/get/put etc call it and return the consumed body)
I'm sorta leaning towards c but it's not the easiest task either and is semver minor
i mean c sounds the least jank
yeah I think so too
its just that i need to modify the API for like 15 classes lmao
could also just add an option to request method that returns full res
isn't that worse
Because like... we typed it as unknown anyways
oh I guess
it doesn't make types that much more complicated
well its definitely a "dont use unless u know what you're doing"
ok yeah that's really clean hahaha
I'll just go for that then
uhhh
I guess I'll make a new PR for that
cc @ruby terrace
and rebase this one to that one
since he did most of rest actually
ckohen my beloved
motivated me to make proxy
ok yes I'll make that PR a thing
returnRawResponse?
ily
but like you need to return the actual response
so people can parse the body
yes
yup
should be p easy
uhh
if Im reading this right
this should go to RequestData right
yeah
seems right
yes
oh wait
ugh lol
SequentialRunner#runRequest doesn't.. get passed those options?
ahh
export type HandlerRequestData = Pick<InternalRequest, 'files' | 'body' | 'auth'>;
I see
well my new field needs to be passed on there
~~one more constraint @tacit crypt - added it to the jsdoc
* <warn>When it comes to non-2xx response codes, this response instance will already be consumed</warn>
shouldn't be that big of a deal yea?~~
oh actually mb, I'm tired
in that case it never returns anyway, it throws, lol.
made no sense
good morning
hahaha
im gonnaaa
add a test for that
or not, I guess, looks like those random options aren't generally tested
I’d rather you make a .raw method
you.. do?
vlad just said that'd be more scuffed
Additionally to request/get/post etc
Nah I think it’d be better
just realized that'd be breaking though
I think
Why
It’s an additional method
What does it break
tbf thats my opinion, i can see why crawl would prefer .raw
well, I guess it depends how we go about it.
if we're looking at REST it's just a new method yeah, but for REST#raw to be able to return a raw response I need to:
a) change IHandler#queueRequest's behavior to return that, and then REST#request calls REST#raw and parses the request - technically speaking this is breaking unless you consider IHandler/SequentialHandler etc to be internal
b) somehow add methods all the way down the chain that instead return raw
internal behavior is not major
but is it internal?
if someone has their own IHandler implementation
you just broke it
because the library will now expect a raw response
rather than whatever parsed data
its not like we support people supplying their own ihandler impl
oh
lol
it seemed like that was the case to me, my apologies
okay then
so it's just a matter of making IHandler#queueRequest return Promise<Response> then
and updating everything up the chain
I knew this was going to be a thing you needed....didn't have a solution so didn't mention it
hahaha
Dispatcher.ResponseData*
because occasionally you do want to still consume the body (on 429 hits)
oh, like, internally?
does undici not have res cloning at all
I was looking into that from my phone when I saw
#7913 in discordjs/discord.js by Larsundso opened <t:1652310378:R>
Listening to <client>.rest response Event breaks <guild>.bans.fetch() and <guild>.invites.fetch()
yeah thats not a problem anymore
lol
well they claimed to be able to repro as of the undici commit
which is what weirded me out
I saw this https://sucks-to-b.eu/YjAukb.png
and I was like
"...is that actually a clone?"
because we use request instead of fetch
(that's when emitting response)
well, alright but
looking at undici readme, you can only consume the body once
so unless that spread does some sort of magic
the undici PR broke the use case of re-consuming the body in the response event
that's besides the point regardless
429 thing :^)
because its nearly impossible
right! so, why we actually need to consume the body on 429s
isn't the data almost always identical to what you get in the headers
or is there some crazy edge case
the only way a clone can be done is consuming the body before emitting a clone and then also using it
I'm thinking you need to consume the body on 429s cause you're not going to send it back upstream at all
not for the data
aaaaah, hm
aren't there cases where it would be sent upstream though
speaking of which....you're gonna want an extra header that allows 429s to pass through (throw on ratelimit stuff)
yeah like
by all means d.js will retry on 429
but eventually if it fucks up past the max retry count
it will reject w/ 429 in which case it goes upstream, no?
that should be the correct behavior
yes, and you need to not consume the body in that case
or if that header is provided, yeah
perhaps I'm just dense but why™️
because you need to send it upstream
,,,but when would I not send something upstream
that's what's throwing me off in this conversation 
like, I'm always going to consume the body
In any case when the proxy is going to retry, you aren't
right
I see
one more thing
maybe 429s do pass through always though, that's a valid option
am I clear to export parseResponse in REST
if we're gonna be adding a way to get raw responses
might as well also have a way to parse them
currently the only thing exported from the utils is
export { makeURLSearchParams } from './lib/utils/utils';
sure
#7929 in discordjs/discord.js by didinele opened <t:1652639581:R> (review required)
feat: REST#raw
📥 npm i didinele/discord.js#feat/rest-return-raw-response
@ruby terrace thoughts on how to handle invalid methods?
technically it seems like /rest doesn't actually check if the method is get/post/put/patch/delete
so I could just bypass the type and let discord throw Method Not Allowed
or should I be sending that myself - in which case it needs to be made clear to the upstream the request never made it to discord
https://github.com/nodejs/undici/pull/1369 I made this pr for getting a "clone" of the consumed body but 1 of the undici maintainers didn't like the idea. 🤷♂️
@warped crater can you capitalise API, please?
everywhere?
lol
I edited the comment a bit late, after @opaque vessel suggested it
I feel like the grammar here is weird anyway
Runs a request from the api made fairly little sense to me
In raw at least
alright
Thank you (':
done
okay well, at this point #7925 is basically ready for review - it's just waiting for #7929 at which point I'll also rebase from main to clean up the commit history
mostly wondering if there's anything else proxy should provide, or if there's any other tests I should be writing that I didn't think of 
Test: does it work
*unit tests 
@ruby terrace bump
I ended up opting for this atm
the proxy should be theoretically transparent, so yeah that
ty
Why not a request option? It can be made using rawResponse option. With the option we will able to get raw response from any request method (.request(), .get(), .post(), etc) and we will be able to set default value for the option in REST options. In my opinion the option is more flexible to use.
because it makes more sense from a design standpoint
than to make everything an option
and make types also more complicated
We can pass the option in the parseResponse function and types won't be so complicated.
still way more complicated then a separate method. And, if you think about it...it is an option, you just provide that option by changing the function call itself slightly (since the other methods are really just helpers for that anyways). Furthermore, it should certainly not be a global option that can be sent on the instance, that will cause many disasters that are better avoided by not even having the ability to mess it up that way.
this.. doesn't actually seem possible with current REST?
rejectOnRateLimit is an option on REST itself and that's it
it can't be passed by-request
also, if you need to use raw you must have some hella specific use case
vlad ^
idgi
reading ckohen's message I replied to
I think he wanted a header that when provided told the proxy to reject on 429 w/o retrying
but if I'm looking at REST correctly there's no actual way to do that per-request no?
it's just a global option you pass on instantiation
Hmm. That ones tough
yeah 
is there a specific reason it's not a per-req option as well
can't we just
make proxy always return 429s
and let the client using the proxy handle the parsing/error throwing?
well, the library itself exposes a middleware function that takes in a REST instance that is already instantiated
so by all means, users are welcome to do that and it's easy to accomplish
if we end up exporting a binary/docker image that just starts up a v simple proxy to fulfil most people's needs
we could default to that, yes
this is more a crawl question but from my pov
my worker rest instance that connects to the proxy has its own rejectOnRatelimit
Proxy always tells me a 429 happened.
My worker instance decides to throw it or not
yea that makes sense
you might want to retry on the worker side
we can figure out such default behavior later when we actually make those binaries, but for now
back to the original topic
could REST support per-request rejectOnRatelimit?
i actually feel like this has more diverse usecase
better question is should it support that
well i can think of why it'd be good
the age old problem
discord bumps a ratelimit to hell and we don't know, our bot starts leaking memory because the poor sequential bucket handler gets queued requests faster than it handles them because of the ratelimits
we had this happen with channel names (no, not an obnoxious clock feature)
and we had no clue what was going on
we were queueing, say 3-4 reqs per 10 minutes and the limit is 2/10min
so I could it see it being beneficial to pass in the option for long limits that you know you don't want to wait for
@solemn oyster did you mean to do this in your last commit to #7934 https://sucks-to-b.eu/HjQrc3.png
Yes, check the reviews
I bumped those a bit too high, they should be using the same version as 13.7.0 does, which is 0.30.0
ah mb
I was looking at it before vlad reviewed that
hi so
is there any reason declaration source maps are not enabled?
it would make working with the monorepo a shit load easier since VSCode "Go To Symbol" would actually take me to the definitions
hmm, the only thing proxy can't forward rn is headers for non-2xx status codes - DiscordAPIError has most of the relevant info (status text, status message, body etc) but not headers
I was thinking of how this could be accomplished and the only way would be to have REST#raw not throw - but rather return responses even when they're not 2xx. I think this would actually be desirable behavior
? cc @wild flax @tacit crypt
all though that becomes.. stupidly complicated to accomplish 
Iirc it would still jump to the .d.ts file with that enabled. I know the TS team is working on something to go directly to the source https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-rc/#go-to-source-definition
it works for me in my monorepo 👀
lemme test real quick to see if it works with djs (all though I don't see why it wouldn't), and if so I might PR
while I was working on that
why was this added in the undici PR lol https://sucks-to-b.eu/CJerc2.png
actually confused why that's in the repo - esp. given VSCode gives no easy option to bypass that once it's a workspace setting
well, after some research seems tsup doesn't support declaration source maps properly, so there goes that dream
I added that with the intent to remove it once the pr was ready but then crawl was fine with it staying in
Is there anything stopping #7929 (REST#raw) from being merged? just needs space to approve, right?
thanks for the merge. #7925 is now ready for review 
I've also added a section for current minor caveats that don't seem easily fixable but that we may or may not want to address
I'm also gonna be running some proper tests on it today to make sure it all works
I only skimmed the code
Is this like a full binary solution
Or is this just a middleware type of thing
middleware with some helpers to build ur own middleware
unsure how we wanna deal with binaries since djs has no precedent doing that afaik
would it even be in the package folder but ignored from npm publish
If it’s a library yeah like a middleware
oh hey im green now
But idk maybe we should make a separate repo
Where we make it a binary and docker image or smth
Because if it was a ready to deploy solution too, it’d be kinda nice
yea that's what I'm thinking too
so there's like
2 exported functions that help you populate a ServerResponse from either an error or a 200 response from discord so you can make your own stuff
and then there's a proxyRequests middleware
that just calls REST#raw in a try..catch
and calls the appropriate method
and ends the response
Yeah idk if you want to wrap this around a node http server
Lmk
I can make a repo for this
that's probs how the default binary would work no?
express etc seems like too much just for this
Yeah
yea ok
yea im setting up a little test project locally rn to see if it all works
and once we merge we can get a repo going for common usecases
There is something else but idk if it’s in node already
They did rewrite the http with some new thing
Kinda like undici
personally what i'll be using for my bot is something that a) logs & collects analytics and b) caches since I like dealing with cache at the proxy level much to your distaste :^)
But idk if they merged it into actual node yet
Idk if it should cache things
yea def not the default one 
that's mostly a me thing
I guess the first one will just proxy and nothing else on top
and then people can like
"hey I have my own custom one that does X"
and if X is popular we can
add more, boom
sure
@wild flax 👀
// proxy.js - this will be our binary minus the worker stuff
import { createServer } from 'node:http';
import { proxyRequests } from '@discordjs/proxy';
import { REST } from '@discordjs/rest';
import { parentPort } from 'node:worker_threads';
const api = new REST({ version: '10', rejectOnRateLimit: () => true }).setToken(process.env.DISCORD_TOKEN);
const server = createServer(proxyRequests(api));
server.listen(parseInt(process.env.PORT, 10), () => {
parentPort.postMessage('ready');
});
// index.js
import { Worker, SHARE_ENV } from 'node:worker_threads';
import { Client, IntentsBitField } from 'discord.js';
import { ProxyAgent } from 'undici';
const client = new Client({
intents: [IntentsBitField.Flags.Guilds],
});
client.on('ready', () => {
console.log('ready');
process.exit(0);
});
client.rest.setAgent(new ProxyAgent(`http://localhost:${process.env.PORT}`));
const restWorker = new Worker('./proxy.js', { env: SHARE_ENV });
restWorker.once('message', () => {
console.log('rest worker ready');
client.login(process.env.DISCORD_TOKEN);
});
➜ node index.js
rest worker ready
ready```
works now
I'll probs test some other stuff here and there but generally speaking at least the gateway connects 
Why does it use workers

idk that was just for my test
I could've just booted it as its own process lol
but I think some people might be inclined to boot it in a worker if they're just using proxy to work around the /gateway/bot ratelimit we were talking about
if their bot is a monolith where they only start one process anyway it's probs easier for them to throw rest into a worker
alright, I'm actually done with my PR now unless changes are requested
Shouldn’t the threadCreate, threadDelete and threadUpdate events be integrated into channel<events>. Then the user can check if the channel is thread and do whatever
I’m not sure if this is already implemented since I don’t follow the GitHub updates that often
We don't change or manipulate events, we follow the Discord API which has them separate
Does not account for emojiCreate and emojiDelete...
Huh, good point, no idea why we do that, though its kinda the opposite example
Thats one event being split out rather than multiple events being merged together
I have nothing to say about it, just look at the pictures.
confused
maybe because... that isn't an accepted format? #fff is parsed as 0x000fff
although yeah that should throw an error instead of accepting it
pretty sure you are supposed to parse #fff as #ffffff
but that's not exactly a hex string, that's a shorthand hex string. tons of things don't support it.
Yeah, not standard
hmm can't we just validate with /^#?[\da-f]{6}$/i
and if that doesn't match then throw an error
cant install stuff into main branch. Need to push commits on the pr
[versions]
yarn -> 3.2.0
node -> 16.15.0
!node_modules 🫂
userUpdate was heavily changed and manipulated in djs iirc
Mon's message was a general statement
i agree, let's stop doing that 
fwiw I hate that, but the pushback for removing it is quite strong
Still voting for we should leave it as it comes from the API
anyone?
This isn't a support channel
Delete node_modules and start again
Yes but I have to commit to my pr and I cannot resolve this issue and it clearly seemed djs issue by reading the errors. This happens only on main branch.
Also there is no node_modules if you see the ss and trying to install node_modules using yarn or yarn install throws the errors from the above ss.
Idk how this aint library related.
in the slash command option classes, you all really need to adjust the names of the addChoice and addChoices methods. They're super easy to mistake particularly if your editor has autocomplete, and the error message you get from the validation is incredibly vague - makes debugging it a nightmare
i think that'll be resolved along with the addField/addFields thing for embeds
I'm happy to hear that 🙂
there's been a lot of discussion around their signatures and inclusion
addChoice has already been removed in the main version of the builders. I believe addField will follow suit
so in the future you'll have to add all choices as an array of string pairs, right?
They take a rest param so not an array, but yes it will take APIApplicationCommandOptionChoice params
At the moment the latest version only takes arrays but I think we're adding back support for both
