#archive-library-discussion

25217 messages · Page 18 of 26

wild flax
#

Sweet

#

That’d be best case scenario then

#

And if there’s issues, we could just send a pr or 2 to them too

#

Since it’s a very specific lib too, so it’s not like we need to hammer through some bureaucracy because it does too much

#

I’m sure we’ll get someone who tries to copy the dep and make a pr and say “one less dep, here you go” but we can just deny those, wouldn’t be the first time

#

Lol

#

I just don’t wanna maintain more code that doesn’t really concern us or rather shouldn’t be maintained by us unnecessarily

outer raven
#

What would you need to maintain?

#

If it works atm there’s no reason for it to break later on

wild flax
#

It’s just not beneficial

#

Look at the code I posted above from the ts lib

#

Shoving all that into a Util file and let it rot there

#

At this point you might as well just install the dep lol

dawn merlin
outer raven
wild flax
#

but why?

outer raven
wild flax
#

Yeah but it shouldn't be our priority or task to upkeep such a util function as a "discord" lib

#

if theres bigger issues at hand in that case

outer raven
# wild flax but why?

My bot is currently 430mb ish because of dependencies mainly and it cannot cross the 500mb because of the host I use. Crossing that would mean having to find a new one which would be a pain. This is my case tho, idk about others

wild flax
#

it just fragments our focus

#

You could look into bundling?

#

tsup for example could very well be used to bundle your node_modules too into a single minified file with a sourcemap

#

so you also get proper line counts in the source files in case an error occurs

outer raven
#

I could look into that but most of that size is a dependency that is on the host only which is needed for a specific package (puppeteer) to work

outer raven
#

Anyway that’s not really the topic of this channel, point is that yeah that could reduce size but it wouldn’t be a lot and I think it’s still possible to avoid deps when we can

outer raven
dawn merlin
#

No the camelcase lib

#

The size difference is negligible

outer raven
#

I’m talking about type-fest which is 155kb (ik, not a lot, but still)

dawn merlin
#

What is the djs’s size?

wild flax
#

I would really like you look into bundling your application honestly

#

you can ignore puppeteer, but youd drastically reduce the size of your application

#

I can maybe write up a guide for the guide page for this

#

But we really shouldn't be "too" careful here

outer raven
wild flax
#

I can maybe also look into bundling d.js itself, so our sourcefiles are minified

#

since they can take up quite some space

dawn merlin
wild flax
#

i wouldnt bundle node_modules though

#

since as a lib that is a bit bad peepoLaughPoint

outer raven
wild flax
#

Harder to navigate how?

#

Nah it was injecting an "import" into a cjs file, nothing to do with fs or path

tacit crypt
outer raven
# wild flax Harder to navigate how?

like when we get errors that link to a djs line instead of an error message, I usually open it to see where it came from and then check other files, if it's all in 1 it could be harder to do this

tacit crypt
outer raven
#

^^ this

outer raven
wild flax
#

well that shouldn't be a main concern, sorry lol

tacit crypt
#

The stack traces aren't an issue, source maps deal with that

dawn merlin
#

I disagree with bundling stuff built for servers

wild flax
#

if im on a server env, I don't go looking into my node_modules to fix something

tacit crypt
#

But like our lib is pretty small either way so I don't see how we'd benefit from minifying it further

wild flax
#

hmmm, 1.19mb unpacked isn't that small

#

lets be real

#

when it could be 500kb

outer raven
tacit crypt
#

Don't bundlers minify our source either way? You want small, use a bundler?

wild flax
#

Sure, that'd be on the user then

tacit crypt
#

I don't see why we should minify our source, I'm sorry

dawn merlin
wild flax
#

I mean at the end of the day, once we switch to TS, we will bundle and minify anyway...

tacit crypt
#

We're what.

wild flax
#

So I am not sure how keeping that equilibrium is important

tacit crypt
#

Why are we minifying .w.

visual hornet
#

well didn't voice already get minified

wild flax
#

Well the output .mjs and .cjs gives is a lot of crap anyway

#

So traversing that is already painful

#

Even without minification

wild flax
tacit crypt
#

Also don't forget our code does fs calls now so careful with minifications and bundling..

wild flax
#

Well that will obviously change

outer raven
#

can it change easily?

#

without hardcoding all exports again

wild flax
#

nothing wrong with hardcoding them

outer raven
#

its a pain to maintain

wild flax
#

we switched to the fs approach because at the time I thought it was a somewhat good idea, but I don't really think so anymore honestly

#

since we had to introduce this webpack hack

#

its ok for now

tacit crypt
wild flax
#

but I would rather not keep it for the long term

outer raven
wild flax
#

no

#

esp not in the future

#

we won't be exposing a lot of private stuff

tacit crypt
#

I still strongly dislike the idea that we'll minify/bundle our sources in the future... There's like..no reason to outside of this size..

dawn merlin
#

Quick question, are we going to use deno for the TS rewrite with npm exports?

wild flax
#

deno*?

dawn merlin
#

Yeah

wild flax
#

Not sure I want to commit to deno and node at the same time

tacit crypt
#

I doubt our lib will be deno compatible?

wild flax
#

Deno usage is very low

#

would also mean refactoring -modules, /voice and /collection

#

Thats... a lot of work lol

dawn merlin
#

Tru

tacit crypt
#

I mean for -types it was dumb easy to do, but for d.js.. the path changes ALONE would be a chore, so I doubt it'll happen soon

#

I mean collections should be deno compatible tbh

#

I don't think we'd need to change anything?

outer raven
wild flax
#

I'd rather use a multi index.ts approach

#

and call export * from 'x/'

#

so youd only need to add the export to the specific sub-index.ts

#

and it will expose itself

outer raven
#

yeah but you still gotta go there and manually add the line

wild flax
#

thats fine

outer raven
#

whereas with an fs read you simply don't have to worry about that

wild flax
#

yeah but I don't see the benefit here

#

How often are you gonna add new classes/files and have to add an export

outer raven
#

every time a new discord feature comes out

dawn merlin
#

They don’t expose everything by default

wild flax
#

yeah, using fs to export your files is quite the anti-pattern

outer raven
#

I'm not sure what most TS libs do tbh, but we're still js and im proposing this for the js lib still

wild flax
#

And I’m not comfortable enough to pioneer a different way here lol

dawn merlin
#

I always see the reexport pattern used in ts libs

wild flax
#

Relying on IO shouldn’t be something we do in the lib

#

Just my 2 cents

#

Save those cpu cycles

tacit crypt
#

I'm not comfortable reading all our directories to do an index.js/ts/mjs/tjs/whatever file either

outer raven
#

but on discord-api-types you have all the v9 stuff in 1 file, so you only export 1 file

dawn merlin
#

That would be the same for nested index.ts’s they reexport and then the root index.ts re-exports them again

outer raven
#

but in djs you have multiple files so even if you have multiple indexes, in the sub indexes you'd have to be require()'ing all of them

dawn merlin
#

Ideally every directory has an index.ts, all you would need to do in the root index.ts file would be reexporting each directory (on the same level).

outer raven
#

yeah that's fine, but it doesn't solve the issue, just spreads it across multiple files

#

"issue" imo ofc

wild flax
#

I honestly don't wanna get too hung up on this whole thing

#

I am pretty dead set on this

#

Sorry

tacit crypt
#

We're not using fs to generate an index.anything file

dawn merlin
wild flax
#

Multi-index file approach

dawn merlin
#

Ah ok

outer raven
wild flax
#

Nope

#

No fs in the lib

dawn merlin
outer raven
#

was at some point, idk if it still is

wild flax
#

Yeah I def wanna move away from that

outer raven
#

:/ aight

slate nacelle
#

I'm +1 on that

dawn merlin
wild flax
#

tip: don't look at it

#

helps me through the day

outer raven
wild flax
#

Because we I merged the fs pr, which I shouldn't have in hindsight

#

but 20/20

#

If anything the less complex code #6102 made things a lot more complex

#

But hey, I was young and dumb

outer raven
#

_how is it complex tho swagcat_cry _

dawn merlin
#

Live and learn

strange igloo
#

people often think less lines = faster/cleaner/better/etc

wild flax
#

I'm saying because of that PR, we had to introduce a more complex method for webpack, since we broke support for it

visual hornet
wild flax
#

So "less complex" ended up being "way more complex"

outer raven
wild flax
#

only web builds were removed

#

not using webpack on the end-user

outer raven
#

I see

dawn merlin
#

So like the dom lib essentially?

wild flax
#

No no, we had specific builds so you can run your bot on a website lol

dawn merlin
#

Hmm ok

wild flax
#

Or the chrome console or whatever

#

But since discord doesnt support that anymore, we removed those builds

#

Doesn't mean we should break bundling overall

solemn oyster
slate nacelle
#

I think that's the wrong PR

solemn oyster
#

Fixed 😅

wild flax
dawn merlin
#

Will do

outer raven
#

and probably 6959?

#

oh i gotta do some too

dawn merlin
#

It’d be amazing if GitHub notified you whenever your pr has new merge conflicts

outer raven
#

you can use an extension

#

it doesn't notify you, but it shows you on the pr list

#

for example this has a merge conflict and it has the icon

tender field
tender field
#

uh-oh i think i failed my rebase

wild flax
#

that looks rather messy

#

you might be better off just remaking it 😅

tender field
#

ah shoot 😅 well thanks, i'll redo it.

wild flax
#

@opaque vessel your PR will be the last blocker for a 13.4 release 👍

#

so whenever you get to updating it with the feedback, we can move forward with that

outer raven
tender field
outer raven
#

Aight will take a look

tender field
#

thanks ! i'll be back in half an hour fyi

outer raven
#

Fixed ^^

opaque vessel
burnt cradle
#

Is the plan to port stuff like MessageButton and MessageSelectMenu to builders?

#

And if so, how far does that extend? Would it include something like MessageAttachment?

copper laurel
#

I did start a Button PR but I didnt like the design and never went back to it

#

Thing is, components basically already are builders in discord.js

burnt cradle
#

Yeah that's why I'm asking

copper laurel
#

I dont really see a need for Attachments to be one

#

Has like 3 properties

tender field
outer raven
#

tbh I think it's good as it is. It mentions the API and client names just like we do in other properties

#

in fact, maybe it should only mention the client name (since the api name can be deduced by the property name) which has also been done on others like GuildMember#premiumSince

#

ops @tacit crypt?

lethal storm
#

Hey library people. Please let me know if this is intended:

With the bot having the "View" permissions in channel 1, I am able to access interaction.channel (as a ThreadChannel) when a command is used in channel 2 (the thread).

If the bot is denied the "View" permission is channel 1 and a command is used in channel 2 (the thread), interaction.channel returns null. The <interaction> itself is a basic object format.

interaction.channel is always available in channel 1. Permission doesn't matter. Is there a reason why the thread acts differently?

dawn merlin
lethal storm
#

No checks in code currently if that's what you mean

#

But Slash commands don't care about channel perms, no?

#

It seems to be cache-related. I can get it it work, but then if I then deny all perms and restart the bot, the interaction.channel returns null again

#

This is all beyond my skill level, but might it be because the bot isn't actually inside the thread?

opaque vessel
outer raven
#

with a lower case b but yes that sounds great, will change

opaque vessel
#

I don't think you need to state its whereabouts in the description

#

At Discord we tend to capitalise the word Boost everywhere

#

Because it's a part of "Server Boost"

outer raven
#

not really

#

and the rest of the sentence is uncapitalized so it doesn't matter

opaque vessel
#

When I said "At Discord" I didn't mean discord.js, I mean literally at Discord

outer raven
#

well but we follow the d.js standard

opaque vessel
#

True, though there's my suggestion nonetheless (:

outer raven
#

yep, committed :D

lethal storm
dawn merlin
#

yeah I did, haven't fully looked into it yet

lethal storm
#

Alright

#

To my un-smart self, it seems like weird behaviour

real jetty
#

djs-modules/core will be using djs-modules/rest and djs-modules/ws instead of internally implementing it for the most part, right?

wild flax
#

core is a module itself

#

discord.js will end up using those

real jetty
wild flax
#

core just houses functions or classes that multiple modules use

real jetty
#

Ah i see

tender surge
#

Hi, do you think it would be possible to add some type hint of the expected interaction type in command data interfaces?

export interface UserApplicationCommandData extends BaseApplicationCommandData {
  type: 'USER' | ApplicationCommandTypes.USER;
  __interaction: ContextMenuInteraction; // Like this
}
#

The issue I'm running in to is that the union type causes issues when attempting to extract the correct properties because you can't get the properties by only referencing either value of the union, and providing both tends to become verbose, after some workaround I managed to reference either union member to get the correct ApplicationCommandData properties but now I essentially have no way to statically determine what interaction type I'm dealing with based on the inferred type

dawn merlin
tender surge
#

Well simply said, it would be nice to be able to do execute(interaction: ApplicationCommandData[T]["__interaction"])

#

Where T is where I reference ApplicationCommandData["type"]

dawn merlin
#

so bascially in your command handler you want the specific interaction type to be inferred?

tender surge
#

Exactly

#

Currently it's not possible because ContextMenuInteraction is completely separated

dawn merlin
#

I can share some code I use in mine to get it to work

tender surge
#

I'm scared now but I'm interested 😅

dawn merlin
#
export type CommandRunner<T extends Interaction> = ({ interaction }: { interaction: T; }) => Promise<void> | void;

export type CommandBase<T extends BaseCommandInteraction> = ApplicationCommandData & {
    run: CommandRunner<T>;
};

export type ContextMenuCommand = CommandBase<ContextMenuInteraction<'cached'>> & (UserApplicationCommandData | MessageApplicationCommandData);

export type SlashCommand = CommandBase<CommandInteraction<'cached'>> & ChatInputApplicationCommandData;

export type Command = ContextMenuCommand | SlashCommand;


// Usage:
const command: Command = {
  type: 'USER',
  async run({ interaction }) {
    interaction // Inferred to `ContextMenuInteraction`
  }
}
#

basically the command kind is inferred based on the type passed into Command

tender surge
#

Why is ContextMenuInteraction different from the others? Oh wait I see now

#

This is what I managed to create

import type { ApplicationCommandData } from "discord.js"

interface LegacyCommandData {
  type: "LEGACY"
  name: string
  description: string
}

type InteractionCommandData = ApplicationCommandData | LegacyCommandData

type InteractionCommandProps<T extends InteractionCommandData["type"]> =
  InteractionCommandData extends infer U
    ? U extends unknown
      ? T extends InteractionCommandData["type"]
        ? U
        : never
      : never
    : never

type Command<T extends InteractionCommandData["type"]> =
  InteractionCommandProps<T>
```In this case it would be solved with `InteractionCommandProps<T> & Record<"execute", (interaction: InteractionCommandProps<T>["__interaction"])>`
dawn merlin
#

You don't need a conditional type to get this to work. A union of ChatInputCommandData | UserApplicationCommandData | MessageApplicationCommandData is a discriminated union. It's discriminated on the type prop. As as long as the type prop is provided typescript can figure out which constituent to use. So adding a branded type to the interface wouldn't add much value.

tender surge
#

I see, ty for the example, honestly the guide screams for a TS version now but that's more of a #archive-guide-discussion thing 😅

#

It's too hard to navigate the types

real jetty
#

RESTManager class does not have JSDoc comments?

outer raven
#

It doesn’t indeed

dawn merlin
real jetty
#

I see

oak quail
#

Discord gives users data for all non-thread channels in the guild, but thread data is locked to users who can access the parent channel (if the thread is private, membership in the thread or the Manage Threads permission is also needed)

#

the only channel data Discord currently sends in interactions is the channel id (which you can access in d.js with interaction.channelId); interaction.channel is loaded from cache

real jetty
#

Is there an official place on djs's github to work on the ts rewrite? Can't tell if im missing something

dawn merlin
real jetty
#

And is the rest module as powerful as the one djs is currently using? Like does it respect ratelimits everywhere it can and such like djs does?

dawn merlin
real jetty
lethal storm
outer raven
#

Well, since the only open PR on collection was closed, can we get a release cookieCat

opaque vessel
visual hornet
#

Why does Util.discordSort sort by id if the rawPosition is the same?
It seems to maybe have some issues, as channels with the same rawPosition have the position in the wrong order
2 channels with the same rawPosition of 0 will have the first channel's position as 1 then 0, for example

#

the rawPosition is linear with some repeats, but where the rawPosition has repeats, the position goes backwards

rawPos 0 0 1 2 3 3 4 4 5 6
pos    1 0 2 3 5 4 7 6 8 9
outer raven
#

Positions are quite a problematic thing so I think that was done as a way to be able to tell them apart. Since Discord doesn’t send the proper position fields, it’s hard to know where stuff is right

visual hornet
#

well it's consistently wrong when the rawPosition is the same, so maybe the a and b could be swapped when checking ids to make it correct?

outer raven
#

that would fix your use case specifically, but break others where that position is correct

#

I don't think you can have a 100% success rate

visual hornet
#

which makes the new channel higher up since it's replacing the position of the cloned channel

outer raven
visual hornet
#

pain

wild flax
#

I think threads are incorrect either way

#

They sort alphabetically I think in the client

#

Which is an accident

visual hornet
#

so, it's an issue upstream that's attempted to be fixed with the position getter?

wild flax
#

Our discord sort should be exactly what the client does

visual hornet
#

well, it clearly isn't, but i guess that's not really an option

wild flax
#

You mean it isn’t for channels either?

visual hornet
visual hornet
#

the repeated rawPos seems to sort by id ascending, but the discordSort method actually seems to sorts descending
@outer raven can you reproduce a scenario where rawPosition is the same and the position is correct between 2 channels? i can't seem to get any cases where it's correct with create either

outer raven
#

I can try but it's really unreliable

#

what type of channels are you working with?

visual hornet
#

TextChannels
GUILD_TEXT

wanton forge
#

Is the <ClientUser>.setPresence() thing buggy for activities? Because there were multiple people in #djs-help-v14 now already whos code didnt work with it, but it worked with <ClientUser>.setActivity()

wild flax
#

@trim quartz can u just copy the client code for positions on channels and threads and give it to us pepeClown

outer raven
wanton forge
outer raven
#

could be an issue in their code, I'm not sure
do you have a reproducible code sample?

wanton forge
#

no.. unfortunately not.. i was just wondering because their exact code worked for me..

vernal adder
#

Can possibly be unknown rate limits if they set at start-up

visual hornet
outer raven
#

Does the api not give a position for threads?

tacit crypt
#

iirc no because threads aren't always present

wispy ingot
#

Hey, (not sure if its good channel, sorry if its not), does anybody know if the new Discord event scheduling feature will be included into the Discord API? And following question is - if it will be, will it be implemented to discord.js library?

visual hornet
#

the first one isn't really a question to djs, but if it's added to the api it'll be added to djs
it probably will be added though

real jetty
#

for discord api implementation you should see in the discord api server, #useful-servers
Afterwards, anything open to bots does end up on djs, someone just needs to make the PR

loud jayBOT
wispy ingot
#

okay, thank you for the info, have a nice day pepolove

frigid sierra
#

Will discord.js include a thing for server events? Like create, edit, delete, etc...

remote wasp
#

yes

visual hornet
#

was just discussed lol

outer raven
#

discord.js supports everything the API does, so those questions always have an obvious answer.
Thing is the API doesn’t currently support events yet, so we’ll have to wait until next week

outer raven
#

@real jetty

#

that's what I mean by "the API doesn't currently support events yet"

real jetty
#

Ok? I'm aware as stated at the start of this conversation. Not sure why it's being repeated

outer raven
#

then why the reaction whAT

outer raven
#

not really

#

you can't use events with bots

#

and self-botting isn't allowed

tacit crypt
#

Ok, then let me be clearer. Your phrasing was terrible

#

The API does support it but bots cannot use it

outer raven
#

yeah so the part that concerns discord.js supporting events isn't supported yet

real jetty
#

waitWhat is mostly because "why repeat things already said to just be less precise"

copper laurel
#

Isn't this exactly why it is, in fact, not an "obvious answer" as you put it? Because the API endpoints for this feature are not yet available to bots, thus it's a Discord feature discord.js is not yet able to support

tacit crypt
#

wh

dawn merlin
#

@opaque vessel for issue #6905, could ThreadChannel#parentId be used?

opaque vessel
#

Sorry, can you elaborate?

dawn merlin
#

On this part of the issue ticket:

However, this condition is always false. this.channelId is the id of a ThreadChannel, but the deleted channel is a GuildChannel. Therefore, the interaction collector is not stopped.

Couldn't you use the parent id against the deleted guild channel id?

opaque vessel
#

I'm kind of lost sorry

#

The parent id of the deleted guild channel would always be a category channel (if one), and this.channelId is the id of a thread channel

dawn merlin
#

oh I see

#

nvm that then

opaque vessel
#

This issue could be partially resolved if one were to not store ids and instead store the structures. But, that would remove the ability to use the interaction collector on guilds the client is not in

dawn merlin
#

another alternative would be to find a way to directly associate collectors with their respective channels, some kind of tree-like structure. When a parent node is eliminated it's children should be as well

#

I think the infrastructure issue has to deal with the fact that threads are more than one layer deep

opaque vessel
#

The thing is, both solutions will not work in guilds the client is not in. The client won't detect if the thread is deleted or if the parent channel is deleted

#

There will always be a possible leak because discord.js supports those types of guilds for the collectors

#

The only real fix is to require a time, then it won't be discord.js's fault (':

#

Then comes the handling of the thread channel shenanigans

dawn merlin
opaque vessel
#

If you mean a discord.js structure, then currently, yes. But that's fixable

#

It's just not fixable for guilds the client isn't in

dawn merlin
#

ah ok

opaque vessel
#

So you can see the real pressing issue here >:

dawn merlin
#

hmm maybe it's worth it to throw an error if you're not in the guild and create limitless collector

#

after all collectors are djs constructs

opaque vessel
#

How would you detect that in the typings o,o

dawn merlin
#

I mean you wouldn't, lol, it's possible but painful

opaque vessel
#

Ya, but this specific collector is alienated from the others due to its unique ability to work on fancy guilds

#

I think the/a fix would ultimately be for the next major version though

dawn merlin
#

For sure

outer magnet
#

Idk but a suggestion that the docs give a note saying CommandInteraction#guild and CommandInteraction#guildId will return null if the client user isn't in the guild / used the command in dms

opaque vessel
#

Isn't that... obvious?

visual hornet
#

well, Message would have to have that as well? and also Typing? and then it would have to be on the base Interaction to let it be shown for the other interactions?

yeah i don't think it's really worth documenting, as jiralite said, it's kinda obvious

outer magnet
#

hmm okay then

visual hornet
copper garden
#

Has it been tested against guild roles?

visual hornet
#

oh shit, it hasn't, i forgot about those.

#

well there's where the positions are correct as is, since the positions are reversed, so ids are sorted descending instead
so i guess there'd have to be some extra option or check for that?

#

discordSort is only being used for those 2 (channels and roles) though, so that should be everything left
so this can be resolved but i don't know what would be the best way to go about it.

analog oyster
#

you could add an option for the sorting order ¯_(ツ)_/¯

visual hornet
#

i did mention that but im not sure what the best way to go about it would be

visual hornet
#

by the way, is there a specific reason parseInt is used instead of, say, Number in discordSort?

opaque vessel
#

Maybe it should be BigInt(a.id) - BigInt(b.id). That code is from several years ago... won't have to slice

visual hornet
#

alright ill include that in my pr

tacit crypt
opaque vessel
#

Noo that won't work

tacit crypt
#

Except it will

#

And sort expects numbers not bigints

visual hornet
#

was typing a question, got answered before i finished meguFace

opaque vessel
tacit crypt
#

Not

#

what

#

I showed

tacit crypt
#

Thats not even the issue (well, it is, but not the issue I'm poking at)

opaque vessel
#

If the return type won't accept big integers then there's no point doing it in the first place then

visual hornet
#

oh whoops

opaque vessel
#

Heck what

tacit crypt
#

Do you see me calling Number twice? meguFace

opaque vessel
#

Oh no

#

Oh great

#

Oh perfect

#

We back

visual hornet
#

also as a side note, im not sure if i set something incorrectly in my dev env, but uh,

#

i haven't modified this or anything, just cloned the repo
eslint is complaining that this should be under node-fetch, but nothing about it shows up with npm test

tacit crypt
#

doesn't hurt to run an npm ci, restart the eslint server and also re-run the test script

opaque vessel
visual hornet
#

aight ill try looking into that, thanks

opaque vessel
#

As long as npm test works fine then all should be good I guess

visual hornet
#

yeah i understand that, just want to make sure eslint is working fine in the ide since the changes im planning are more than just swapping a and b like i initially planned lol

opaque vessel
visual hornet
#

i got to this, but it feels kinda clunky, im not sure if this could be improved in some way?

Number(a instanceof GuildChannel ? BigInt(a.id) - BigInt(b.id) : BigInt(b.id) - BigInt(a.id))
opaque vessel
#

Suppose you should use variables to make it less clunky? Shrugs

visual hornet
#

as an iife? or just make it a block and return the result?

opaque vessel
#

Yeah it looks like a block would be more readable

#

Like so?

const aId = BigInt(a.id);
const bId = BigInt(b.id);
return Number(a instanceof GuildChannel ? aId - bId : bId - aId);
visual hornet
#

aight

#
return collection.sorted((a, b) => {
  const aId = BigInt(a.id);
  const bId = BigInt(b.id);
  return a.rawPosition - b.rawPosition || Number(a instanceof GuildChannel ? aId - bId : bId - aId);
});

so this is what i've got now, anything else to be desired here?

opaque vessel
#

@dawn merlin your question you just asked isn't for me, that's for Discord

dawn merlin
#

ok, I just wanted to verify that this currently how discord is sending events

opaque vessel
#

I don't really know how ddevs and that all works (not in there), but you should probably ask in there. If you don't want to, I can get an answer for you during working hours

dawn merlin
#

i'll just make an issue ticket on the dapi-docs github, someone from ddevs will probably answer

golden mortar
#

here's what attachments is ```js
attachments: [ { id: '0', description: undefined } ],

visual hornet
#

aren't you supposed to use files to send them initially
and attachments is mainly for editing?

golden mortar
#

no clue, these were just added as the result of a rebase

#

removing those lines makes everything work fine once again

visual hornet
#

still have no idea what attachments are really for :/

golden mortar
#

neither do I but i'm wondering if that's a bug, extraneous code that can be removed, or if i need to implement a fix on my pr

ruby terrace
#

the naming scheme is kinda weird, files is the array that is processed into the attachments array, the attachments array in MessagePayload is the thing actually processed into formdata.
There is also the attachments key in Messages, which is JSON data and completely separate.

golden mortar
#

so any reason sending the attachments array would cause a 400 status from discord's side?

#

i have no idea how to fix the issue i'm having minus just removing that section of code linked above

#

the exact error:

DiscordAPIError: Invalid Form Body
attachments[0]: Attachment data not found

code 50035

ruby terrace
#
- if (file?.file) body.append(file.key ?? `files[${index}]`, file.file, file.name);
+ if (file?.file) body.append(file.key ?? file.name ?? `files[${index}]`, file.file, file.name);

You made this change to the formdata appending, which I believe causes that error. Take a look at the new attachment uploading stuff in the api docs, seems that was missed in the rebase

golden mortar
#

that fixed it! but that brings up a second question:

the issue is that file.name wasn't und/null so the name would default to that.. but if file.key was a valid name, wouldn't it throw an error there as well?

ruby terrace
#

the key is used for stickers only, because the formData key needs to be "file" for that

#

the stickers endpoint uses formdata but is more json styled

golden mortar
#

interesting 🙂 thanks for the insight & the help

ruby terrace
#

np, its all kinda confusing, I wouldn't know about that stickers stuff if I hadn't just implemented that in /rest

visual hornet
#

(unrelated to the current discussion)
i think im doing something wrong with testing
i only added a require and changed discordSort, but when testing im getting Util.setPosition and Util.idToBinary not being functions, logging Util gives an empty object
i tried requiring the index through a filepath, and also by npm pack then npm i, and they're yielding the same results

copper laurel
#

requiring the index where?

visual hornet
#

in testing code, i just did require('../../discord.js/src/index.js')

#

well actually it was esm that i already had from earlier

copper laurel
#

circular requiring index is generally very very bad, any chance thats happening?

visual hornet
#

oh it wasn't inside djs

#

i had a test file inside a different project in the same directory

flint zephyr
#

Is there any package that can perform automated tests for bots using slash commands?

#

pls ping if answering

visual hornet
#

this isn't really a question for this channel, you can just write tests yourself

burnt cradle
#

@tacit crypt has there been any discussion/decision on the issue of replacing ow in builders? Sorry for the bump but esm support being broken feels kinda high priority

tacit crypt
#

ow, my validation...

fiery shore
#

Discord.js seems to lack some API fields according to the Discord API Documentation here:
https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure
The attributes min_value and max_value is not present in the type ApplicationCommandOptionChoice and also not set in transformOption().
See:
https://discord.js.org/#/docs/main/stable/typedef/ApplicationCommandOptionData
https://github.com/discordjs/discord.js/blob/stable/src/structures/ApplicationCommand.js#L330

#

I see that an PR is being merged 4 days ago. Let me use the github master version then

opaque vessel
#

It's just not in stable

real jetty
#

Because of the way dynamic works, shouldn't gif be excluded from the format type here as it'll already use gif when possible if you specify the dynamic flag?

dawn merlin
#

Possibly, but iirc providing both isn’t technically incorrect

opaque vessel
#

What if you don't know if the user has an animated avatar icon? Providing your desired format there is a fallback

#

Feels like the default for dynamic should be true

outer raven
#

the defaults for images should be changed a bit imo

#

but yeah it's a bit risky to provide a gif format

copper laurel
#

Im pretty sure the defaults we have now exist for a good reason, this discussion comes up every so often

opaque vessel
#

It feels a bit odd imo to specify a dynamic property to get the actual avatar icon that is being used by the user in the right format... wouldn't it be more desirable to replace that with a static property where you decide whether you want to receive their URL in a non-animated format?

So { static: false, format: "jpg" } would get the .gif and fallback to .jpg if it's not animated
{ static: true, format: "jpg" } would get the .jpg always

I'm not sure where this can falter tbh

copper laurel
#

And whats the default, static: false?

#

I just dont really see what benefit this has over setting a format, and a property which will override that for animated avatars

opaque vessel
#

Yep yep, static: false is the default. If anything, this seems more like a helper property by discord.js shrugs

#

If you think about it, fetching the avatar's hash will return it in a format starting with a_ if it's animated. discord.js converts every image received to static by default, though that's not necessarily what should be happening? It should be returned as-is, and the user can specify if they want to enforce the image to be static

copper laurel
#

Not exactly? The default format is webp

opaque vessel
#

The animated file format Discord uses is .gif

#

At least in the client

copper laurel
opaque vessel
#

Yeah but currently, you have to specify if you want it to be dynamic

copper laurel
#

Yes I know

opaque vessel
#

Sorry didn't see the code block with the huge thing being collapsed x_X but yes!

#

Tbh at that point the property becomes useless, if you want a static image, just supply "png" or "jpg" or something

copper laurel
#

uhh.... no? Because it will default to gif?

opaque vessel
#

Can you elaborate

copper laurel
#

Supplying "png" would be for deciding the format if it is not animated

#

Unless you also provided static: true

#

Or the reverse with dynamic: supply "png" to always get a png, or supply "dynamic: true" to get a gif if its animated

opaque vessel
#

What I'm saying is that if we flip the logic to ensure all the URLs made are dynamic by default, you wouldn't need the static property. Since all animated avatars on Discord are of a .gif format, then the other formats .webp, .png, .jpg and .jpeg are all for static images so... they would never attach themselves onto animated avatars

#

Supplying one of them implies you want them to be static

copper laurel
#

No it doesnt

#

That's breaking the existing functionality of being able to specify the static image format while also resolving an animated one if applicable

#

Currently:
() - webp
({ dynamic: true }) - gif > webp
({ dynamic: true, format: "png" }) - gif > png
({ format: "png" }) - always png

With your proposed static: false default:
() - gif > webp
({ static: true }) - webp
({ format: "png" }) - gif > png
({ static: true, format: "png" }) - always png

If you remove static/dynamic entirely, you lose that gif > png use case

#

The fallback scenario is gone

opaque vessel
#

I got you yeah just at the last moment, thank you for being concise there haha

copper laurel
#

Otherwise the change is literally just swapping the logic on the first two outputs

opaque vessel
#

Yeah exactly, I'm pretty sure everyone everywhere is favouring always using dynamic: true, so... we should probably change that

copper laurel
#

Not true, I dont

opaque vessel
#

Well, mostly, at least, but the logic I follow is if the user object logs the avatar's hash as "a_..." and you run .avatarURL(), one new user would likely think they're going to receive the animated avatar

#

Uh anyway... I guess that's a change for version 14?

copper laurel
#

Would definitely be breaking yes

opaque vessel
#

Cool, alright, thank you for this lil' conversation (':

outer raven
#

On that note, I believe there’s no good reason to use webp as the default is there? Discord doesn’t have a default, the client used png and webp doesn’t even support transparency

outer raven
#

It does not

#

If you try to set something’s icon or avatar to a webp image it loses the transparency, I’ve tried it

dawn merlin
#

Well the format does dunno why it doesn’t work for discord

outer raven
#

¯_(ツ)_/¯ but supplying png for that works as intended

#

So maybe that default could also be changed for v14?

#

Actually now that I look into it, webp is supposed to provide quality images with less size but it’s made mostly for browsers, and djs doesn’t work on a browser, so maybe that was forgotten when that was removed ¯_(ツ)_/¯

outer raven
#

Using discord.js’s methods

#

So for example guild.setIcon(client.user.avatarURL())

dawn merlin
#

the client gui doesn't even allow you to upload webp

tacit crypt
#

If discord cannot process webp's that's an issue on their end not ours

#

Also the client uses webp whenever possible

#

If a platform doesn't support it, then it defaults to png

wild flax
#

You cropped it with discords internal crop tool, which gets rid of any transparency

#

As for our methods, the problem exists most likely with their image microservice

outer raven
copper laurel
outer raven
#

Because the client is based on web so it needs smaller images, but if webp doesn’t work properly with djs I don’t think we should use it right?

tacit crypt
#

You do realize that it's not discord.js's fault that Discord's media whatever the hell it's called breaks webp transparency, right?

#

And also, we already default to jpegs for uploads

#

if you send discord a webp image thats on you

#

I don't see why we should change internals for this

#

Maybe we have a bug that we send the image wrong to discord when using an URL

outer raven
#

My point is that if you don’t specify a format, discord.js sends webp which then breaks the image. I understand this may not be the library’s fault, but it’s something that can be fixed by changing the default, and then if the user decides to specify webp it’s their own fault

wild flax
#

in this case it is the libs fault because of what vlad said

#

we just assume its a certain extension

#

which could potentially mean gifs break too, except if we check only for gifs

outer raven
#

But where’s the code that’s defaulting to jpeg?

remote wasp
#

@outer raven the regex you gave for INVITES_PATTERN doesn't work for events, need some help with Client#fetchInvite

outer raven
#

which PR? I don't remember touching that one 😅

outer raven
#

I remember that now

#

not sure if you agree but I feel like it would make sense for an event not to match with the invites pattern

#

so that regex does work for events only (not sure if the https should be matched or not)

remote wasp
#

Client#fetchInvite uses that pattern to resolve the invite code, so we need something that matches event's link too

outer raven
#

clicking an event link does make you join the server, so I guess you can leave the invites pattern unchanged, but that method could be interesting if there is an endpoint for that (not sure, haven't really looked at the documentation properly)

#

actually, since you wanna capture the event ID and not the invite id, lemme update that comment

lofty birch
outer raven
#

oh really?

#

what are those snowflakes

lofty birch
#

android client share does at least, and I'm not entirely sure

#

one of them is obviously the event ID

#

oh guild ID and event ID

outer raven
#

yeah that makes sense

#

but that doesn't render

#

oh but it does work

lofty birch
#

yeah it's weird

#

you only get it from Android afaik

outer raven
#

on iOS I get missing permissions Thonk

remote wasp
#

Now, the issue is that how to add a way to let users pass an event id to Client#fetchInvite without a breaking change, because it only takes invite resolvable as argument

outer raven
#

well make it a second arg

#

but it's really annoying that you cannot resolve an event from an invite, maybe we could add the method and warn users that it would make 2 api calls?

#

that's gonna be controversial though since every other method in djs uses 1 unless given certain options

outer raven
lofty birch
#

that's weird

#

anyways, I just wanted to point it out because I've seen that form a few times

outer raven
#

honestly not sure what to do with it

tacit crypt
remote wasp
#

yup, that's what I decided too. Had to go with ClientFetchInviteOptions because FetchInviteOptions is taken. Could change that to FetchGuildInviteOptions in v14 👀

visual hornet
pure flare
wild flax
#

Yes, Ill be handling that in a few days time

#

Thank you for figuring that chain of deps out and making it to the source to get it fixed 🙏

pure flare
#

Ok cool, and then @discordjs/opus will also need to be updated downstream. Thanks.

#

Lol i've been chasing it all the way down from the top.

#

also prism-media will need to start referencing whatever updated version of @discordjs/opus that integrates the fix but i'll bug them about it once that happens

oak quail
analog oyster
#

that was not the point. the point is that the link that is copied on android is different than the one on the other platforms

lethal frost
#

Has there been chat about creating a general .send() method on interactions that will send a message no matter if a reply was already sent (by calling .followUp()) or deferred (by calling .editReply())?

analog oyster
outer raven
#

Apparently I was the only one who disliked that but the issue was closed, so I'm not sure what that means
Usually djs doesn't like utility methods that have other workarounds iirc, but it's a matter of opening a PR and seeing the feedback ig

opaque vessel
#

Personally also don't want it tbh

#

Monbrey's comment in there is what I like

dawn merlin
#

Yeah it's an abstraction that is misleading

copper laurel
#

Crawl never really agreed to it, looks like it was summarised by my comment

#

None of the reactions on the initial post are from maintainers

outer raven
#

Crawl did disagree to my comment, along with 6 other people

#

not sure why

#

but yeah I assumed it wasn't something ppl wanted

golden mortar
#

Usually djs doesn't like utility methods that have other workarounds iirc, but it's a matter of opening a PR and seeing the feedback ig
I've got a question regarding this since it's true to my knowledge: why does the lib include Formatters? It simply exports some functions from builders but they're not used in the code whatsoever. Plus it adds 12 11 dependencies to the main lib

opaque vessel
#

Hi @dawn merlin - thank you for letting me know about deprecated usage of ThreadMemberManager#fetch() <:

Looking at it closely, how come the second parameter is an object and not the first? If one wanted to fetch all members in a thread but not cache them, the method would have to be called as fetch(undefined, { cache: false }). Why not fetch({ cache: false })? I may have missed something x:

dawn merlin
opaque vessel
#

Sorry, I don't follow. Before this commit, there was no Snowflake type?

dawn merlin
#

oh sorry it was a boolean before

opaque vessel
#

Ya! Exactly haha

#

So imo, I thought it would be better if a boolean was passed, it would be internally converted to { member: undefined, cache: boolean, force: false }

dawn merlin
#

yeah I think that's what it's doing

The member to fetch. If undefined, all members

  • in the thread are fetched, and will be cached based on options.cache. If boolean, this serves
  • the purpose of options.cache.
#

So ig maybe a deprecation warning isn't needed

opaque vessel
#

You're willing to keep the boolean property?

#

That does look like it'll also solve the issue

#

So I guess, either make a change to keep the boolean property, or convert the first parameter into an object shrugs

dawn merlin
#

oh I'm caching on, you're saying have one property that's boolean|object?

#

catching*

opaque vessel
#

Ya ya

#

Or just object alone at that point maybe, up to you

dawn merlin
#

well for v14 just an object but to prevent breaking changes im pretty sure it needs to be a union

opaque vessel
#

Ya

dawn merlin
#

honestly if you don't mind it can probably be an addendum to your PR, but if you'd rather not I can make a PR

opaque vessel
#

Would you pretty please mind making one <3

dawn merlin
#

for sure (as in I wouldn't mind)

opaque vessel
#

(:

dawn merlin
#

is there a way to destructure and have a named parameter on a function? ie:

function foo(options { a, b })
visual hornet
#

for the same parameter? i don't think so
but you could just destructure out afterwards since you'd need to check for the boolean first

dawn merlin
#

yeahhhh, I also have to deal with default values as well but I think thats the only way

visual hornet
#

i think the default value should be fine, since it would only trigger if neither the object nor the boolean were given

dawn merlin
#

oh wait I just realized you can get the first argument via arguments[0]

visual hornet
#

this will be changed with a breaking change in v14, right

dawn merlin
#

yeah

wild flax
#

It’s a metric that is rather bad to go by. You obviously shouldn’t add all kinds of junk, but at some point it gets rather silly

golden mortar
#

I agree in some cases but adding 11 deps just so people can import formatters from discord.js and not builders is rather strange imo

#

especially since in v13 dev a bunch of old methods that weren't used in the codebase got removed as well

#

just wondering what benefit having Formatters in the lib gives over importing djs builders instead?

vernal atlas
analog oyster
#

in that case options will not have the a and b fields

#

the best you can get is ```ts
function foo(options) {
const { a, b } = options;
}

vernal atlas
#

i mean yes but thats just kind of silly IMO, at least for making a function in djs

dawn merlin
#

@copper laurel ban

copper laurel
#

what

dawn merlin
#

There was a nitro scam someone deleted it

dawn merlin
#

@opaque vessel looks like I need to improve those type guards 😅

opaque vessel
#

Is this regarding issue #7001? o,o

dawn merlin
#

Yeah

opaque vessel
#

Sweeping the channel manager isn't actually supported so... dunno if you want to do that shrugs

dawn merlin
#

Hmm it isn’t? I thought sweeping any cache was valid

#

Ik extending caches isn’t supported

opaque vessel
dawn merlin
#

oh yeah I'm just being dumb, I literally said extending isn't supported, but thats the only way to change the sweep settings anyways.

#

I could've sworn it throws if you do that, so im not sure how the person in 7001 got around that

#

oh it just emits a warning...

loud jayBOT
visual hornet
#

could i request for someone to check if putting those changes in breaks Util in the same way mine did?

loud jayBOT
worthy coral
#

For CommandInteractionOptionResolver#getChannel, where does the Option.channel come from? Discord does not list this as a valid property from Application Command Interaction Data Option.
From what I can see, minimal transforming is done, but I've only looked at the AutocompleteInteraction#transformOption

worthy coral
copper laurel
#

Im not sure what you think the problem is here?

worthy coral
#

I got really confused because the signature didn't have a resolved param, but it will still being passed anyways. Type safety is the issue

copper laurel
#

The autocomplete interaction doesn't, so it is useless here

#

But autocomplete is only for string types anyway

#

Its a JS library there is no type safety lmao

#

This is the full one

worthy coral
#

Trying to fix that amandabox

copper laurel
#

So yeah, it probably shouldnt pass resolved in the autocomplete interaction

worthy coral
#

That was my problem because my brain is melting trying to make things type safe

#

sorry for confusion

rustic boughBOT
outer raven
#

you mean this?

#

but that does exactly the same as the typeguards, except without type safety. If that's not it then I'm not sure what you're looking for

#

determining if it's a select menu, button, command or context menu requires 2 checks, which are done by the typeguards, so why not just use those?

#

the only alternative to the typeguards is doing the checks they run yourself, which is less clean imo. There are all sorts of typeguards both for specific interaction types and more generalist ones so idk why you can't just use those

#

and by that I mean isApplicationCommand and isCommand for example

copper laurel
#

Yeah I really don't understand this question. It's the "how do I do <thing> without doing <correct existing way to do thing>"

#

What's wrong with the methods

tender surge
#
- public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => Awaitable<void>): this;
+ public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => Awaitable<unknown>): this;
```Do you think this would be possible?
real jetty
dawn merlin
tender surge
outer raven
#

Yeah in the end it doesn’t really matter what the listener returns, so I’d say any would be fine too

tender surge
#
export function createEvent<T extends keyof ClientEvents>(
  cb: (
    ...args: [...args: ClientEvents[T], prisma: PrismaClient]
  ) => Awaitable<void>
) {
  return cb
}

export default createEvent<"messageCreate">(async (message, prisma) => {
  if (x) {
    return message.channel.send(...) // Promise<Message> not assignable to void
  }
})
```If you do change to unknown in your handler, you can't dynamically pass it to client.on
burnt cradle
#

just return on the line after the send

outer raven
#

Yeah but that makes the code unnecessarily more bulky when it doesn’t make a difference if you return a message

tender surge
#

any is fine too

vernal atlas
#

return void await x
return void x

real jetty
vernal atlas
#

yeah, i was just suggesting an alternative soloution to their problem, at least until if/when its changed

dawn merlin
#

if you make the return type a promise of unknown it's misleading because it implies that return value is used somewhere else which it isn't

tender surge
#

What about any? Or a type alias that represents something with the value of any

#

It just adds extra noise atm, especially with

padding-line-between-statements:
  [error, { blankLine: "always", prev: "*", next: "return" }]
```I get it's my issue but the return type doesn't matter
dawn merlin
dawn merlin
tender surge
#

eslint rule to always add a new line before a return statement (separation of concerns preference)

dawn merlin
#

ig disable it then? lol

opaque vessel
#

What about passing a type parameter to specify the return type, or will that not work

dawn merlin
#

it would but I don't really see what justifies it?

opaque vessel
#

Shenanigans

tender surge
#

I think it would be nice to support as many JS patterns as possible, generic return type would be fine too

outer raven
#

I just don’t get the issue with having it return any

tender surge
#

For semantic reasons, but generic return type fixes that

outer raven
#

What would that generic type look like

tender surge
#

public on<TReturn = void, K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => Awaitable<TReturn>): this;

outer raven
#

TReturn should probably come first so you can specify it easily

tender surge
#

True, edited

outer raven
#

Why not default it to any?

dawn merlin
#

My issue is that it enables code to be written with unclear intentions, it's unclear if the return value is consumed by the client or not. Also from a documentation standpoint when the return type is Promise<unknown> or Promise<any> it seems like you need to return something, and may confuse people.

zenith oracle
#

IMO, it's just confusing to add a return type of any/unknown as users may think that a value should be returned or that it can be used somewhere

dawn merlin
#

^

tender surge
#

I mean isn't Awaitable confusing for the exact same reason?

#

I read it as oh I can await this and it might return something

dawn merlin
#

No awaitable just means it can be await'd that doesn't imply anything is returning a value

tender surge
#

Could endlessly discuss those being different, anyway just something I faced today, I'll stick to ts-ignore

dawn merlin
#

or just put return on another line

outer raven
dawn merlin
#

It's confusing because any could be a value

outer raven
outer raven
dawn merlin
#

the return value doesn't matter because it's never used, when I see a return type of any I honestly assume something needs to be returned

tender surge
#

You can't tho..

zenith oracle
# zenith oracle IMO, it's just confusing to add a return type of any/unknown as users may think ...

I don't see a reason why it should be any/unknown too.
I mean, yeah, in a command handler having a return type of any would be more comfortable but also lead to unexpected issues, like we may return a string because we think that it'll be sent as a reply for example, so it's always a good practice to put your return statements outside any expression.
Also iirc the return type of that function in the built-in EventEmitter is void...

outer raven
dawn merlin
#

Doesn't matter it's still not as clear as void

#

void is always going to be more explicit and less of a gray area

tender surge
zenith oracle
#

Iirc it was changed to Awaitable because of an eslint rule that didn't allow the use of an async function in that case.
It's however really different from any/unknown

dawn merlin
#

it doesn't matter it's a callback, Promise<void> | void are void once resolved

tender surge
#

eslint didn't allow the use of async functions
ts doesn't allow me to return methods early while it's still technically valid, just like you're able to await

#

I honestly see both cases as supporting JS patterns, I do get where you're coming from

dawn merlin
outer raven
tender surge
#

Just a bit upsetting as most ts features that are being added are to be able to type JS patterns

#

Yea I know I can work around it

dawn merlin
#

honestly imo returning a value for a method that's supposed to return void isn't a great pattern anyways

tender surge
#

🤷‍♂️

wild flax
#

its technically not correct, yes

#

since whatever you return, if its fails, is unhandled

#

so what we do is fine and correct

real jetty
#

Correct me if im wrong about this behavior but shouldn't this always be a guildmember because of the typeguard?

burnt cradle
#

try inCachedGuild instead of inGuild

real jetty
#

Yeah that did it, forgot about that one 😅

opaque vessel
#

inGuild() there refers to just a guild, whether it be cached or not yeah

real jetty
#

Is there a set in stone idea for what djs-modules/ws would be responsible for? Is it a general powerful websocket module that's capable at handling any url type, or one that's specific to discord only and can do all of the stuff that the current djs one can do?

outer raven
#

Are there any plans to move util functions to their own package like a @discordjs/util of sorts? Some of these functions are quite useful and people don't always need the full library to work with them

wild flax
#

like?

outer raven
#

That’s the one that sparked this idea, could look into the others too

solemn oyster
#

SnowflakeUtil is likely superseded by @sapphire/snowflake, which @discordjs/rest uses

wild flax
#

Yeah snowflake Util isn’t super useful honestly

crisp forum
#

is there a reason Shard#eval can't have a context passed into it? (like why wasnt that implemented)

outer raven
slate nacelle
crisp forum
#

ig so but i added it into the src of the pkg should i pr it?

slate nacelle
#

Gladly

outer raven
#

Can we get a way to specify the type of the components in an action row, through something like new MessageActionRow<"SELECT_MENU">() like was done for collectors?

#

cc @dawn merlin 👀

dawn merlin
outer raven
#

you might be able to mix component types in the future though, so that type could support multiple component types

dawn merlin
#

Because the array of rows isn’t guaranteed to have the same component types

outer raven
#

I'm talking about individual rows through

#

so in that case I wouldn't if I just created the action row with the type like we do with collectors

dawn merlin
#

But if you access the the row by index how it know the type? Because the array of rows is a less specific type

outer raven
#

idk about you but I never access a message's rows, I just store the row in a variable and modify it later on

#

and that's the use case I'm talking about, since you can't get more specific when accessing a message's components array (and perhaps you shouldn't)

visual hornet
#

what if the first component you add to a messageactionrow changes the class or something

dawn merlin
visual hornet
#

oh wait no that wouldn't work

outer raven
#

like this

#

and the idea was to do this

dawn merlin
#

So addcomps would only take select menu components?

visual hornet
#

could you maybe add a typeguard based on the type like how you do it with Interaction

outer raven
dawn merlin
#

Ok I see

visual hornet
#

...yeah.

i shouldn't be here

dawn merlin
dawn merlin
outer raven
dawn merlin
#

those both seem to work, I'm assuming by reset you mean setting the components to [] and splice should only take components of the correct type

outer raven
dawn merlin
outer raven
dawn merlin
#

oh wait I'm dumb, yeah it's doable

#

This works as expected

// @ts-expect-error
selectMenuRow.components = [new MessageButton()];
outer raven
#

ready for the PR? I'd be glad to test it

void rivet
#

wait can you send stickers with interaction.reply?
i didn't find it on the api docs but the typings for the method tells you you can since it extends BaseMessageOptions

outer raven
void rivet
#

you do it 🙃

outer raven
loud jayBOT
#

pr_open #7012 in discordjs/discord.js by ImRodry opened <t:1637436949:R> (review required)
types(WebhookMessageOptions): disallow stickers
📥 npm i ImRodry/discord.js#types-webhook-stickers

outer raven
#

@void rivet ^^

void rivet
#

👍

outer raven
#

In what scenarios can Invite#uses not be null? I already fetched an invite and I didn't get that data

slate nacelle
#

I'd assume when obtained through Client#fetchInvite.

outer raven
#

that's what I did though and didn't get the uses, same thing when looking at the raw data from the API

#

the uses property appears in an "invite metadata object" in the discord docs that is supposed to be extra info that may be present, but they don't mention when that can be present

vivid field
outer raven
#

oh so we only get that data when fetching the invite on the guild? PEWHmmmmZoom

#

I think the Invite class could use some improvements on its documentation to specify these quirks

vivid field
#

the docs are open source ¯_(ツ)_/¯

outer raven
#

I'll give it a shot with a PR, let's see how that goes

vernal adder
#

Audit log documentation needs some updating as well, seeing that the description of <GuildAuditLogsEntry> is literally just "Audit logs entry."

dawn merlin
outer raven
#

you could add the typeguard as well to make it work when you receive it too ig

dawn merlin
#

Hmm

real jetty
#

Why are API objects not exapanded upon? For instance i don't see why we couldn't provide support for APIMessage#edit() (you could get an api message when you followup an interaction)

#

I don't see the purpose of just dumping the api obj on them when we're supposed to be wrapping around said api object

dawn merlin
# real jetty Why are API objects not exapanded upon? For instance i don't see why we couldn't...

Api objects are usually returned when you’re client isn’t a bot in the guild. The api* objects are just the raw data returned from the api. The reason we don’t wrap them in a class is because the cache cannot be properly updated because it doesn’t receive guild events. In fact in the case of the message, you can’t edit a message purely based on the message recieved it needs to be done via the interaction (since the bot isn’t present in the guild)

outer raven
#

But yeah if it’s an interaction you should be using the interaction methods instead

peak mauve
#

discord.js\src\util\Util.js:413

if (typeof data !== 'string') throw new error(errorMessage);```

Couldn't the data be tried to convert to a string first?

#

interaction.reply(client.ws.ping) will crash the process because it is a number

outer raven
peak mauve
#

oh yeah I remember this working in previous versions

visual hornet
#

Are we still doing consistency with the api with types?
message type 20 is listed as CHAT_INPUT_COMMAND in the api docs, but it's APPLICATION_COMMAND in djs, which i guess could be somewhat confusing since CONTEXT_MENU_COMMAND is a seperate type, type 23

outer raven
#

something for v14

visual hornet
#

didn't see any issue/pr for it
i guess this would need some type updates, which i don't know how to do, so... unless someone's free to do it, i'll make an issue in a bit

outer raven
#

all you gotta do is change the value in constants

#

and then change the typings accordingly

#

but it's a semver major so ¯_(ツ)_/¯

visual hornet
#

eh it could be left for later

outer raven
#

constants line 428

#

I could make the PR rn

visual hornet
#

go ahead

outer raven
copper laurel
#

client.users.cache.size has only ever been cached users

#

Never ever has this property been populated with all users in all your bots guilds

#

Fetching all members is absolutely not recommended at all

#

Please go back to support, this is not a library discussion issue

outer magnet
#

@copper laurel

copper laurel
#

ty

arctic pebble
#

Hello

#

About the presence update

#

I think game activity presence should be separated

wild flax
#

No idea what you are asking

arctic pebble
#

to know if there is a game u a member is playing

#

coz when i use presenceupdate

#

while playing a game then i have set a custom status or some other activity like listening to spotfy, it will give my undefined or the latest activity for that

void rivet
arctic pebble
#

I have this bot that gives role when a member is playing then remove the role when he is not, then when he have set a custom status then removed it, it will remove the playing role coz, i get an undefined precense activity

#

but he is still playing

#

So the playing role shouldn't get removed to him

void rivet
#

so what do you suggest we do?

arctic pebble
#

i don't know if the issue is from the presence update or my code

void rivet
#

i guess your code
members can have multiple activities, right? your code probably wasn't made to deal with that

arctic pebble
#

but would it be possible to retain the array no. from the oldpresence to newpresence

ornate topaz
#

you do know that you can just see what an activity is, and then check any other one that is present? it doesn't end on [0] or [1]

#

you have multiple tools in javascript to do that

void rivet
#

you can find it by it's type, which for you would be playing

arctic pebble
ornate topaz
#

then don't do that.

arctic pebble
void rivet
#

yeah it's not really an issue with the library, it is your code
how you dealt with presenceUpdate

arctic pebble
#

I just compre new from old

#

Thanks @void rivet I now have an idea

sonic condor
#

Why does MessageEmbed has .video property if you can not embed a video?

unique axle
#

received embeds can have them, you can just not send them from bots

#

hence why there is access to it but no means to set it

smoky dawn
#

Is there a specific reason to why the Client constructor doesn't default to no intents?
Like, this just seems like unnecessary:

const client = new Client({
    intents: []
})

I'd much rather just do this:

const client = new Client()
tacit crypt
#

Because intents are mandatory

smoky dawn
#

So basically because people NEED to know they aren't enabling any intents?

tacit crypt
#

Because people NEED to provide intents to connect*
EDIT: They need to specify that they either want no intents or some intents so users know about them

smoky dawn
#

You don't need any intents to run the bot, though?

tacit crypt
#

I don't know if Discord lets you connect if you specify intents 0, but our lib does require at least GUILDS intent to work most of the time (iirc with interactions that's less the case)

opaque vessel
#

The fine line here is omitting the intents and providing no intents. You should explicitly specify your intents and discord.js shouldn't shortcut it

tacit crypt
#

TIL (and it makes sense I suppose)

#

for the sake of explicity, we make intents mandatory

smoky dawn
#

Alright, thanks guys.
This is probably better for the majority, as they wouldn't understand why is working, before realizing they were missing intents.

#

Glad to clear up, that it was done for a reason.

limpid oxide
#

isnt it supposed to be true by the default?

tacit crypt
#

More of a #djs-help-v14 question but since you're providing allowedMentions in your client thats what we use when it's missing from your reply calls

outer raven
tacit crypt
#

thats more of an API question but no, it shouldn't, because if you specify allowed_mentions at all Discord just disables it by default

outer raven
#

Ah I see

slate nacelle
#

That's some weird behavior on Discord's end.

outer raven
#

Probs an API bug then

tacit crypt
#

Tho maybe I'm wrong, citation needed

#

But I'm fairly certain thats how it is

slate nacelle
#

I think if you do not send allowed_mentions, all mentions are parsed (and replied user is true), but if you specify it, replied user defaults to false.

tacit crypt
#

I wouldn't say its an API bug but an annoyance personally

outer raven
#

but probably not worth the bug report

tender field
outer raven
tender field
#

sure sure do it when you have time! no worries

#

thanks for your help (in dms)

oak quail
outer raven
oak quail
#

well it was discussed with multiple staff back then

outer raven
#

Ah alright

#

Questionable but sure

median hazel
#

i dont know if this is the right place to ask but do we know if we will be able to insert any of the current message components into the new modal feature coming?

visual hornet
#

modal feature..?

oak quail
median hazel
oak quail
#

api-questions would be the best for now

limpid oxide
wild flax
#

nope

vivid field
#

if you pass no allowedMentions then the default is true

#

only if you do pass them you overwrite that default

limpid oxide
#

ah i see

oak quail
#

its actually marked as default false in discord's docs (which was confirmed in the discussion with staff), because it is in the object

#

it doesnt exist at all if the object doesn't exist

#

and d.js doesnt seem to modify it so... shouldnt it be the same as Discord and say false?

slate nacelle
#

allowed mentions itself is optional too and that missing defaults too "all mentions"

#

At least that's my explanation

outer raven
#

Should default to Discord’s default but they should enable repliedUser since that’s the default on the client

oak quail
#

the client doesnt send allowed mentions by default

outer raven
#

That’s what I’m saying

copper laurel
#

Its really not as complicated as this discussion would suggest
allowed_mentions not provided - all mentions are enabled, including replied_user
allowed_mentions is provided - only those mentions listed are enabled, which mean replied_user only if provided

#

Theres no reason to think of it as some separate default, its just an allowed_mentions property

#

Discussing the fact that the desktop client has a toggle in a default state is irrelevant, this is the bot API, not a desktop client

copper laurel
#

This seems more like support than a discussion for this channel

outer raven
sage frigate
copper laurel
#

At least, not in djs

outer raven
#

Thought this worked before but yeah you're right. That's quite annoying but I can see it's not something looking to be improved on

copper laurel
#

I dunno, I think the design is fine. parse is mutually exclusive to the arrays. You can:

  • parse all users and/or roles and/or everyone
  • array of users and parse all roles
  • array of roles and parse all users
  • array of roles/users

And add replied_user to any of the above

outer raven
#

yeah but if you don't specify any of those values, they should use the default that is used when the object isn't passed at all

#

so allowedMentions with a roles array and nothing else, repliedUser would be true for example

#

because I think that's what the average user would assume would happen

#

and the current behavior is also inconsistent with the docs, which say repliedUser defaults to true

copper laurel
#

Eh, I disagree that they would or should assume it, thats their fault for making assumptions

#

I do agree on the docs though, its just annoying to accurate represent both

wild flax
#

You overwrite the default, so the default doesn't apply anymore

#

I don't understand how that concept is so hard to grasp

copper laurel
#

I dont think it should be marked as defaulting to true though, since doesnt that imply the code sets it to true if not provided?

outer raven
wild flax
#

Yes you do

copper laurel
#

You're making the same mistake I originally called out

wild flax
#

We don't merge with our defaults

copper laurel
#

Stop thinking it has a separate default to allowed_mentions

#

It does not

wild flax
#

If you pass ANYTHING into allowedMentions it will overwrite our default

copper laurel
#

If you change allowed_mentions you have overriden the default

#

There are no sublevels

wild flax
#

lets say you do:

allowedMentions: { parse: ['users'] } }

now that means our default which includes repliedUser will be overwritten with JUST what is above

#

so if you wanted repliedUser to still be true, you have to manually include it

copper laurel
#

So having said that, shouldnt the docs specify the default as none rather than true, because we do NOT default that property if not provided

wild flax
#

we do default it, just not merge it

#

its a different discussion

copper laurel
#

I cant find where we do

outer raven
#

but it would be really easy to apply these defaults by deconstructing the object. I was trying to test it but idk where this is parsed if it is at all

copper laurel
#

But we dont want to because Discord doesnt

outer raven
#

we can do things that Discord doesn't tho

copper laurel
#

I cant find anywhere that we actually set a default for allowedMentions or repliedUser

outer raven
#

yeah me neither

copper laurel
outer raven
#

aight ig ¯_(ツ)_/¯

wild flax
#

Ah, its on the message options for it

#

Well the problem with that is that it probably used to be the behaviour when that PR was made

#

and it was documented as a discord default

#

Which is something we indeed usually don't do

copper laurel
#

Probably yeah

#

Where as now, at no point do we apply a function default parameter for that, so it should probably have the default removed from the JSdoc too

#

Because I do read that as implying that if repliedUser is not supplied in allowedMentions, discord.js sets it to true

#

(and we dont)

outer raven
copper laurel
#

Well in case I havent been clear, I do not think we should have a different default behaviour to Discord

outer raven
#

I believe it wouldn't be the first time we fix little quirks of the discord API to make them more logical

#

of course this "logical" is very subjective, but I think it's what the users would assume the default behavior to be

#

default being not passing the parameter, regardless of the object being passed

#

because whether you pass allowedMentions or not, the properties you don't specify are set to undefined, which should always be replaced by a default value

wild flax
#

Its a bit scary defaulting to discords defaults

#

Since they could change, and preferably we want to too, but thatd require a new major

outer raven
# wild flax Its a bit scary defaulting to discords defaults

well in this case we'd be defaulting to a default that isn't always used and if it does change we can handle that in a semver major, without the behavior simply changing without any version bumps (although this is unusual, discord usually doesn't ship a lot of breaking changes without version bumps)

#

so if we set defaults on the library's side, we can change those defaults without relying on what Discord does, and follow semver properly

solemn oyster
#

@visual hornet have you tried moving the require to below module.exports?

#

At the very bottom

visual hornet
#

which require? the GuildChannel one i added in Util?

solemn oyster
#

Yeah

visual hornet
#

yeah that.. solved it...
what changed here?

solemn oyster
#

CommonJS considers a module "loaded" when at least one export or when module.exports is defined, so by moving the import to the bottom, you're requiring that file from a loaded module, so when it's required back, it works as intended

visual hornet
#

hm i see it's also used in TextBasedChannel with a comment, I'll copy that comment and commit that
thanks

cursive cradle
#

Is there any reason why UserManager#send doesn't exist so you can send a message to a user without fetching them first?

#

I noticed MessageManager#delete where you can delete a message without fetching it so I feel like UserManager#send would also be rly useful

solemn oyster
#

Can probably be done

analog oyster
#

how will you get the dm channel?

opaque vessel
#

That's not relevant, when one is created it'll return the existing item

analog oyster
#

let me rephrase: how will you achieve that in a single request

opaque vessel
#

Don't believe you can

cursive cradle
#

Oh, I didn't realize that :( nvm

analog oyster
#

I guess the current User#send method already does 2 requests if the dm channel isn't cached

opaque vessel
#

Yea that's right, so you'll essentially be doing nothing under-the-hood, just refactoring

#

Anyway on that topic, I suppose you can move .createDM() and .deleteDM() there

cursive cradle
outer raven
#

there are a lot of methods that could be moved to managers honestly

#

just like the message manager has

#

I tried to do some of those at some point but there were just too many

#

so that'd be a good way to start

cursive cradle
#

I feel like there aren't too many methods that couldn't be moved to managers

outer raven
#

Just out of curiosity, what’s blocking the GuildScheduledEvent PR and the release of 13.4?

dawn merlin
outer raven
#

I really hope that’s not the case cuz I think a lot of people, including me, could use it on a dev release at least :/

#

But it’s the first time I ask about this PR

dawn merlin
#

I don’t make the rules shrug

outer raven
#

Yeah ik, just saying it would be nice

solemn oyster
dawn merlin
#

@outer raven are you looking for to do a PR?

outer raven
dawn merlin
outer raven
outer raven
#

I have no clue how that works tbf

#

What I was thinking was the PR to add methods to managers

dawn merlin
dawn merlin
burnt cradle
#

You might want to wait on any major builders prs until after the validation lib gets changed so you won't have to rewrite ur pr halfway thru

dawn merlin
#

This is tru

burnt cradle
#

Also adding the new components would be bigger than you think cuz there's currently no component infrastructure so you'd have to write it completely from scratch

outer raven
# dawn merlin Which methods?

A lot of methods that are currently handled by classes and not in managers, similarly to the guildmember and message managers. I don’t know which can be moved which is why I gotta look into it better, but there were some ideas above about dms for example

solemn oyster
#

rn there's a critical bugfix PR pending for review, among a few more

outer raven
#

I saw the dapi types pr was merged which I thought was the only blocker

solemn oyster
#

Yes, Rodry. Check the list of pull requests, and you'll see

outer raven
solemn oyster
#

It's not related to scheduled events