#archive-library-discussion

1 messages · Page 25 of 1

outer raven
#

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

tacit crypt
#

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

outer raven
#

it would make sense to say that if you had any plans to change these things, but it doesn't seem like you do

solemn oyster
#

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

copper laurel
#

This is not a constructive conversation, rather just accusations and insults towards the maintainers of the library.

ember steeple
#

@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

outer raven
#

It’s not about the difficulty of doing one over the other, it’s about things like this

fading magnet
#

tf

#

are they gonna kill off v13 like they said with v12 but never did

unique axle
#

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).

fading magnet
#

like oh yea v12 is gonna be dead in a few months!1!!1

unkempt bear
#

Not anymore. It's been extended

#

That being said, move to v13 :)

unique axle
#

cool, so if you know this doesn't need to be discussed - so why even bring it here in the first place

ember steeple
solemn oyster
#

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

fading magnet
#

well know i do bc im here

outer raven
warped crater
#

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"

unkempt bear
#

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

outer raven
# warped crater even in this instance you're being told the new interface for the method is mean...

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

outer raven
#

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

strong hull
outer raven
#

the shocker here is them not caring about what the community wants and going against it

wild flax
#

Oh don’t worry, we do care.

#

Just the bigger picture and not so much a vocal minority

slim moat
visual hornet
#

aren't there only like 4 constructors that you're supposed to use

wild flax
#

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

raven juniper
#

Or just pin to a commit if you're using dev for a feature

solemn oyster
#

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.

golden mortar
#

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
void rivet
golden mortar
#

having issues with InteractionCollector too, it's documented too, just doesn't work

void rivet
#

do these just not support custom reasons

#

looking at the code i don't see this, nor do i see MessageCollector using custom reason

visual hornet
#

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

golden mortar
#

okay so it's just broken, ill see if i can make a pr to fix it

loud jayBOT
outer raven
copper laurel
#

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?

outer raven
#

idk why that workaround is there but it looks useless

copper laurel
#

The interaction that sent a message is not the same interaction as this quite often though

outer raven
#

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

copper laurel
#

It passes both though

#

The first parameter is this, why would it be passed twice

outer raven
#

yeah but why

copper laurel
#

I didn't look into the functionality, I fixed a bug

outer raven
#

the class does that anyway

copper laurel
#

Yes I know

outer raven
#

if id is null it uses the interaction ID

copper laurel
#

if the optional message id isn't passed

#

Which certainly suggests there a valid reason for it to be passed

outer raven
#

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

copper laurel
#

I don't know I didn't build those classes. I fixed a bug and have no interest in arguing about it

outer raven
#

but i wanna know if this is a bug worth fixing or not

copper laurel
#

Well the library isn't broken now. Seems worth it to me

outer raven
#

what kinda answer is that

copper laurel
#

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

outer raven
#

all i asked was if there was another bug here jeez

oak quail
wild flax
#

rip

real jetty
#

⚰️

green valley
#

why does discord.js still use node-fetch v2.6.6 and not 2.6.7

warped crater
#

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"

cursive jackal
green valley
#

but dependabot is too worried for me

warped crater
#

unlucky

vernal rose
green valley
#

yarn didn't did that

oak quail
#

is it intended that GuildExplicitContentFilter and GuildDefaultMessageNotifications aren't exported? seems like an oversight

#

this should be ActionRowData right?

dawn merlin
#

uh which branch of the docs are you looking at?

oak quail
#

main

#

also this in SelectMenuComponentOptionData

dawn merlin
#

In that case yeah it should be ActionRowData

dawn merlin
oak quail
#

in the types, SelectMenuComponentOptionData.emoji is ComponentEmojiResolvable, which is APIMessageComponentEmoji | string, but looks like it doesnt actually handle strings in v14?

dawn merlin
#

In discord.js it does in builders it doesn’t

oak quail
#

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

dawn merlin
#

Hmmm it should work, it was added

oak quail
#

this is in an object being passed directly to interaction.reply

dawn merlin
#

Oh you’re using the json not the builder

#

Iirc json doesn’t take emojis directly as strings anymore

oak quail
#

d.js passes it to a builder internally ```js
const components = this.options.components?.map(c => (isJSONEncodable(c) ? c : new ActionRowBuilder(c)).toJSON());

outer raven
#

Getting a 405 error on the permissions set endpoint saying "Method not allowed", how do we set permissions now? Does djs need to update?

analog oyster
ruby terrace
#

working on it, you cannot set permissions without an oauth2 bearer token

ember steeple
outer raven
#

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

ruby terrace
#

that's not how that works, if they removed it, you'd get a 404

copper laurel
outer raven
ruby terrace
#

that is correct yes

copper laurel
#

Yeah not really a deprecation either in fairness

#

Since its an immediate breaking change

outer raven
#

I thought Discord was against these kinds of immediate changes but god was this update dropped awfully

ember steeple
copper laurel
ruby terrace
#

We literally warned them against doing this too

opaque vessel
#

Angry

hearty nymph
#

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?

visual hornet
hearty nymph
mighty bough
#

is stable branch still receiving updates?

honest barn
#

it will once a new update gets released (v14)

zenith oracle
#

13.7 should be the next stable version actually iiuc

honest barn
#

it should but it wont go to the stable branch, i guess it would be in the 13.x branch

copper laurel
#

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

honest barn
#

i meant getting something merged into the literal stable branch

copper laurel
#

We'll likely also have a stable v13.7 and a stable v14.0 at some point

honest barn
#

from main

copper laurel
#

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

honest barn
#

o

outer raven
#

@ruby terrace does this mean your PR will add support for user tokens or what exactly is this about?

ruby terrace
#

bearer tokens, as it says, user tokens are not bearer tokens

outer raven
#

they are ?

#

bots use bot tokens, users use bearer tokens

ruby terrace
#

users use tokens, no prefix

outer raven
#

Then what’s a bearer token

faint grove
#

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.

unique axle
#

this is absolutely not a discussion for here, tbh

faint grove
#

True, sorry.

tacit crypt
outer raven
#

Why would djs support that now if it doesn’t anywhere else

ember steeple
warped crater
#

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.

tacit crypt
#

Such as add guild member

outer raven
#

Will there be guides on how to get such token and how to update permissions through the bot?

copper garden
#

There's alr a section in the guide for obtaining an OAuth token

unique axle
#

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

outer raven
#

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

unique axle
outer raven
#

alright, thanks

outer raven
#

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?

tacit crypt
#

internet had a stroke

#

Not related to djs either, its just that when we tried a request, your internet said shrug (you can read up what ECONNRESET means online)

outer raven
#

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

inland panther
#

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

tacit crypt
inland panther
#

Generally speaking the documentation of changes in behavior due to enabling partials is lacking in Client events

#

Or am I missing something Thonk

warped crater
#

this goes for the gateway as well

#

nothing is gonna be more informative than "econnreset" coming straight from your OS

outer raven
#

seems like not even the code knows

solemn oyster
#

It's meant to test extreme cases

golden mortar
golden mortar
warped crater
#

probably just that, if non-sensical cases are handled "correctly"

golden mortar
#

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

solemn oyster
#

Or could be April Fools

timber owl
#

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?

solemn oyster
#

No

timber owl
#

Why not?

solemn oyster
#

Because npm v7 pulled a funni and tries to install peer deps

timber owl
#

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

solemn oyster
#

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

timber owl
#

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

void rivet
timber owl
#

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

outer raven
#

what would be the benefit of adding that then

oak quail
#

@dawn merlin I'm confused, channel flags have nothing to do with permissions v2

#

the pinned flag is for forums

dawn merlin
#

Oh lol my bad I knew it was something newer I’ll fix that

real jetty
#

They do, also this is not the channel for support it's #djs-help-v14, this channel is only for developing the library

real jetty
#

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'),
    }]
})
golden mortar
#

at that point it's just easier to use the actual type than enum resolvers, it even tells you its name

wild flax
#

Its because theres a version mismatch currently probably

#

between builders and djs

outer raven
#

@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

real jetty
dawn merlin
# real jetty I feel like it's some sort of bug now, because if i type `5` in the value of the...

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 shrug

#

We could use mapped types to make the enum resolvers more specific, but not sure how feasible it is.

golden mortar
real jetty
#

I meant 10 different enums from one import actually like ComponentType,
ApplicationCommandOptionType and many more

vernal rose
vernal rose
golden mortar
# real jetty I meant 10 different enums from one import actually like `ComponentType`, `Appli...

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

real jetty
#

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.

golden mortar
#

I have that in my bot (a Component factory), on a v14 branch, using only discord-api-types.

real jetty
#

Open source?

#

Nvm

golden mortar
#
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

zenith oracle
#

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

golden mortar
#

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

dusky crown
#

Hey guys, I see there’s permissions on commands, is there any update on that on discordjs?

unique axle
dusky crown
#

Thanks

mighty bough
#

do v14 types still need fixing?

void rivet
#

as in? what specifically?

vernal rose
mighty bough
#

this doesn't work, did I make a mistake?

components: [
  new ActionRowBuilder().addComponents(
    new ButtonBuilder()
      .setLabel("Send Embed")
      .setCustomId("send_embed")
  )
]
opaque vessel
#

Yes

ember steeple
#

can someone tell me why there's ban and kick method on GuildMemberManager but theres no timeout method

#

please

haughty cypress
#

there is

#

<guildmember>.timeout()

opaque vessel
#

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

visual hornet
#

it isn't its own route

ember steeple
ember steeple
visual hornet
#

you could just use the existing edit method

ember steeple
visual hornet
#

you don't need to let me know your own decision lol

real jetty
#

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.

visual hornet
#

im pretty sure a dapi wrapper counts as discord focused

real jetty
#

Ahh alright then, my bad

outer raven
#

why is djs using experimental node features? Shouldn't we wait for them to come out in stable versions of node?

opaque vessel
#

I think that specific one is stable in a later Node.js version. Nothing was changed between the phase so it should be okay

golden mortar
#

or like is there anything the maintainers have talked about in private that would hold it up

copper laurel
#

No specific internal discussions thats Im aware of, probably just needs reviews

uneven blaze
#

Is there some kind of roadmap to the ts rewrite plans?

honest barn
#

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

unique axle
#

milestones are not dated and progress is not necessarily indicative of a release

honest barn
#

oh

unique axle
#

it's not lying, you just misinterpret milestones that have no dates

tacit crypt
#

ws you mean?

honest barn
void rivet
#

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

honest barn
#

hm makes sense

stray shell
#

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.

unique axle
stray shell
#

thank you, information

bitter peak
#

was the oeis link really necessary lol

unique axle
#

yes, oeis is nice and more people should know about it firY

timber owl
#

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

real jetty
timber owl
#

huh, good to know

#

thanks

vernal rose
solemn oyster
tacit crypt
#

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

solemn oyster
#

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

opaque vessel
#

Being back stringified big integers :c

wild flax
#

@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

golden mortar
#

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

wild flax
#

newest undici means you need to update?

golden mortar
#

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

wild flax
#

ah

golden mortar
#

anyways, setting agent with RESTOptions should be fixed now

wild flax
#

The fix for the 2nd might actually collide with the fix for the first global dispatcher

golden mortar
#

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)

wild flax
#

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

wild flax
#

having the options work is good enough imo

#

thanks for fixing that

#

and have shared ratelimiting

#

👍

golden mortar
#

and now setGlobalDispatcher works, what a weird issue. Once I updated discord.js' undici it worked instantly

wild flax
#

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

golden mortar
#
(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],
});
wild flax
#

weird

#

I guess ill take your word for it

golden mortar
#

are you using client.login? I omitted it from my example

wild flax
#

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

warped crater
#

wait, you still need a way to skip djs' ratelimiting right?

wild flax
#

if it returns no headers, theres no issue

warped crater
#

ahhh right, if it strips them its cool already

#

wow

#

end of an era

wild flax
#

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

warped crater
#

yea I know the feeling, this is super nice

wild flax
#

and undici makes this really painless

#

while node-fetch its super painful and needs another dep

#

lol

warped crater
#

technically this was possible before with node-fetch with a hacky agent yea

wild flax
#

yeah, node-http-proxy-agent or something

warped crater
#

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)

wild flax
#

yes but this is nicer

warped crater
#

yea f sure

#

this is the proper way

#

exciting

#

now to wait for a gateway pkg from you all :^)

wild flax
#

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

warped crater
#

owoah bless

real jetty
#

Is there a reason why this can't be supported on api messages?

analog oyster
#

an APIMessage is a raw object from the api

real jetty
#

Like the one I showed, obviously not all of them can be reflected but some of them definitely can be.

golden mortar
#

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

dawn merlin
real jetty
vernal rose
#

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

dawn merlin
#

you should probably be using MessageEmbed in v13 for now

vernal rose
#

well maybe I'm can just cast it as most of the ppl won't use new builder with v13

analog oyster
#

does it not work if you use .toJSON() on it?

vernal rose
honest barn
outer raven
#

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

solemn oyster
#

You can just open the changelog, Dependabot also includes a link to the full changelog

manic cairn
analog oyster
#

the amount of commits in your pull request doesn't matter, they squash them when merging

manic cairn
#

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

clever summit
#

there's a new git option to use the pr title when squashing so it shouldn't matter

analog oyster
#

and if they really cared about the first commit msg, they can also just change it themselves when merging

lapis echo
#

You can literally edit what the commit message will be when using squash & merge

golden mortar
outer raven
#

dependabot shows the change log so you dont have to open a new tab

#

so the libraries should make their changelogs properly

golden mortar
dawn merlin
#

I'm spitballing here, but I wanna say it had something to do with the form data types? Pretty sure undici fixes that though

golden mortar
#

I made a pr to remove them 🤷‍♂️

dawn merlin
#

Does it compile without it errors?

golden mortar
#

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?

dawn merlin
#

Are you compiling or running the tests?

#

Also it looks like it’s from djs not rest

golden mortar
#

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(?)

wild flax
#

Gotta build too

lethal echo
#

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

solemn oyster
#

That's 7 links, not 30.

lethal echo
#

didn't know about it, thx

solemn oyster
#

Tip: you can also middle click links to open them in a new tab, makes opening them a lot faster 👀

outer raven
#

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

silent field
#

why wasn't v13.7.0 not announced? It was released on github and npm but never here.

lethal echo
wild flax
#

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

long dew
#

the site libray is not working

#

im clicking on stuff and nothing happens

opaque vessel
long dew
worldly sail
opaque vessel
#

The typings should not include a number there. It will always be a string

tired tartan
copper laurel
#

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

tired tartan
#

that why 13.7.0 wasn't announced in #announcements, well good for you then ig

worldly sail
opaque vessel
#

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

worldly sail
#

okay, i won't pr then

oak quail
unique axle
#

"needs" is a bit of a strong word here

vernal rose
dawn merlin
#

I’m pretty sure docs doesn’t know how to represent protected methods

opaque vessel
#

Should all protected methods be hidden, or a badge stating they're protected?

#

Could probably tweak something about that

outer raven
#

Imo they should display as private since protected methods are private with extra steps

tacit crypt
#

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

vernal rose
outer raven
tacit crypt
#

i mean even privates can, just that TS will scream unless you use [] accessing

fresh crater
#

hi guys

outer raven
warped crater
#

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)

loud jayBOT
warped crater
#

This I've started up a basic PR and would appreciate some general guidance as I work through it owoah

#

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

warped crater
#

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

golden mortar
#

why not just return your own Agent (maybe extending ProxyAgent) where you can get all of that info?

warped crater
#

hmm

#

could you exemplify

#

I can't really imagine how that'd work

warped crater
#

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 meguFace

warped crater
#

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

tacit crypt
#

i mean c sounds the least jank

warped crater
#

notLikeCat yeah I think so too

#

its just that i need to modify the API for like 15 classes lmao

tacit crypt
#

could also just add an option to request method that returns full res

warped crater
#

isn't that worse

tacit crypt
#

Because like... we typed it as unknown anyways

warped crater
#

oh I guess

#

it doesn't make types that much more complicated

tacit crypt
#

well its definitely a "dont use unless u know what you're doing"

warped crater
#

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

tacit crypt
#

cc @ruby terrace

warped crater
#

and rebase this one to that one

tacit crypt
#

since he did most of rest actually

warped crater
#

ckohen my beloved

#

motivated me to make proxy

#

ok yes I'll make that PR a thing

warped crater
#

ily

tacit crypt
#

but like you need to return the actual response

#

so people can parse the body

warped crater
#

yes

#

yup

#

should be p easy

#

uhh

#

if Im reading this right

#

this should go to RequestData right

#

yeah

#

seems right

tacit crypt
#

yes

warped crater
#

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

tacit crypt
#

good morning

warped crater
#

hahaha

#

im gonnaaa

#

add a test for that

#

or not, I guess, looks like those random options aren't generally tested

wild flax
#

I’d rather you make a .raw method

warped crater
#

you.. do?

#

vlad just said that'd be more scuffed

wild flax
#

Additionally to request/get/post etc

#

Nah I think it’d be better

warped crater
#

just realized that'd be breaking though

#

I think

wild flax
#

Why

#

It’s an additional method

#

What does it break

tacit crypt
warped crater
#

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

tacit crypt
#

internal behavior is not major

warped crater
#

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

tacit crypt
#

its not like we support people supplying their own ihandler impl

warped crater
#

oh

tacit crypt
#

lol

warped crater
#

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

ruby terrace
warped crater
#

hahaha

ruby terrace
#

because occasionally you do want to still consume the body (on 429 hits)

warped crater
#

oh, like, internally?

#

does undici not have res cloning at all

#

I was looking into that from my phone when I saw

loud jayBOT
ruby terrace
#

yeah thats not a problem anymore

#

lol

warped crater
#

well they claimed to be able to repro as of the undici commit

#

which is what weirded me out

#

and I was like

#

"...is that actually a clone?"

ruby terrace
#

because we use request instead of fetch

warped crater
#

(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 :^)

ruby terrace
#

because its nearly impossible

warped crater
#

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

tacit crypt
#

the only way a clone can be done is consuming the body before emitting a clone and then also using it

ruby terrace
#

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

warped crater
#

aaaaah, hm

#

aren't there cases where it would be sent upstream though

ruby terrace
#

speaking of which....you're gonna want an extra header that allows 429s to pass through (throw on ratelimit stuff)

warped crater
#

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

ruby terrace
#

yes, and you need to not consume the body in that case

warped crater
#

or if that header is provided, yeah

#

MegaThink perhaps I'm just dense but why™️

ruby terrace
#

because you need to send it upstream

warped crater
#

,,,but when would I not send something upstream

#

that's what's throwing me off in this conversation meguFace

#

like, I'm always going to consume the body

ruby terrace
#

In any case when the proxy is going to retry, you aren't

warped crater
#

right

#

I see

#

one more thing

ruby terrace
#

maybe 429s do pass through always though, that's a valid option

warped crater
#

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';
tacit crypt
#

sure

loud jayBOT
warped crater
#

@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

golden mortar
solemn oyster
#

@warped crater can you capitalise API, please?

warped crater
#

everywhere?

#

lol

solemn oyster
#

I edited the comment a bit late, after @opaque vessel suggested it

warped crater
#

I feel like the grammar here is weird anyway

#

Runs a request from the api made fairly little sense to me

solemn oyster
#

In raw at least

warped crater
#

alright

opaque vessel
#

Thank you (':

warped crater
#

done

warped crater
#

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 owoah

tacit crypt
#

Test: does it work

warped crater
#

*unit tests meguFace

warped crater
warped crater
ruby terrace
#

the proxy should be theoretically transparent, so yeah that

warped crater
#

ty

cursive jackal
# wild flax I’d rather you make a `.raw` method

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.

wild flax
#

because it makes more sense from a design standpoint

#

than to make everything an option

#

and make types also more complicated

cursive jackal
#

We can pass the option in the parseResponse function and types won't be so complicated.

ruby terrace
#

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.

warped crater
#

rejectOnRateLimit is an option on REST itself and that's it

#

it can't be passed by-request

tacit crypt
#

also, if you need to use raw you must have some hella specific use case

tacit crypt
#

idgi

warped crater
#

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

tacit crypt
#

Hmm. That ones tough

warped crater
#

yeah catHmm

#

is there a specific reason it's not a per-req option as well

tacit crypt
#

can't we just

#

make proxy always return 429s

#

and let the client using the proxy handle the parsing/error throwing?

warped crater
#

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

tacit crypt
#

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

warped crater
#

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

tacit crypt
#

better question is should it support that

warped crater
#

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

warped crater
solemn oyster
#

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

warped crater
#

ah mb

#

I was looking at it before vlad reviewed that

warped crater
#

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

warped crater
#

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 catHmm? cc @wild flax @tacit crypt

#

all though that becomes.. stupidly complicated to accomplish meguFace

dawn merlin
warped crater
#

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

#

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

golden mortar
#

I added that with the intent to remove it once the pr was ready but then crawl was fine with it staying in

warped crater
#

Is there anything stopping #7929 (REST#raw) from being merged? just needs space to approve, right?

warped crater
#

thanks for the merge. #7925 is now ready for review owoah

#

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

wild flax
#

I only skimmed the code

#

Is this like a full binary solution

#

Or is this just a middleware type of thing

warped crater
#

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

wild flax
#

If it’s a library yeah like a middleware

warped crater
#

oh hey im green now

wild flax
#

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

warped crater
#

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

wild flax
#

Yeah idk if you want to wrap this around a node http server

#

Lmk

#

I can make a repo for this

warped crater
#

that's probs how the default binary would work no?

#

express etc seems like too much just for this

wild flax
#

Yeah

warped crater
#

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

wild flax
#

There is something else but idk if it’s in node already

#

They did rewrite the http with some new thing

#

Kinda like undici

warped crater
#

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 :^)

wild flax
#

But idk if they merged it into actual node yet

#

Idk if it should cache things

warped crater
#

yea def not the default one kek

#

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

wild flax
#

sure

warped crater
#

@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 kek

wild flax
#

Why does it use workers

warped crater
#

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

warped crater
#

alright, I'm actually done with my PR now unless changes are requested

sleek kelp
#

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

copper laurel
#

We don't change or manipulate events, we follow the Discord API which has them separate

quiet viper
#

Does not account for emojiCreate and emojiDelete...

copper laurel
#

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

sour ferry
#

I have nothing to say about it, just look at the pictures.

warped crater
#

confused

visual hornet
rough roost
#

pretty sure you are supposed to parse #fff as #ffffff

visual hornet
#

but that's not exactly a hex string, that's a shorthand hex string. tons of things don't support it.

copper laurel
#

Yeah, not standard

visual hornet
#

hmm can't we just validate with /^#?[\da-f]{6}$/i
and if that doesn't match then throw an error

fervent walrus
#

cant install stuff into main branch. Need to push commits on the pr

[versions]
yarn -> 3.2.0
node -> 16.15.0

#

!node_modules 🫂

real jetty
warped crater
#

Mon's message was a general statement

unique axle
#

i agree, let's stop doing that firFine

ruby terrace
opaque vessel
#

Still voting for we should leave it as it comes from the API

copper laurel
#

Delete node_modules and start again

fervent walrus
# copper laurel This isn't a support channel

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.

coral cave
#

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

visual hornet
#

i think that'll be resolved along with the addField/addFields thing for embeds

coral cave
#

I'm happy to hear that 🙂

visual hornet
#

there's been a lot of discussion around their signatures and inclusion

unkempt bear
#

addChoice has already been removed in the main version of the builders. I believe addField will follow suit

coral cave
#

so in the future you'll have to add all choices as an array of string pairs, right?

unkempt bear
#

They take a rest param so not an array, but yes it will take APIApplicationCommandOptionChoice params

copper laurel
#

At the moment the latest version only takes arrays but I think we're adding back support for both

unkempt bear
#

stable doesn't, but main does

solemn oyster
honest barn
ember steeple
#

because in paython they use snake case

visual hornet
#

^ and dapi uses python

tacit crypt
visual hornet
#

hasn't there been talks of like

  • camelCase along with snake_case
  • seperate camelCase and snake_case classes
  • camelCase conversion method
    and they all basically ended with too complicated and unnecessary?
outer raven
#

not really, snake_case and camelCase are supported on most things atm

outer raven
#

what's the URL for the new discord-api-docstypes website?

tacit crypt
#

Patience

#

lol

analog oyster
#

there's a new discord-api-docs website?

tacit crypt
#

Well vercel ruined the surprise

#

But please wait till I announce it properly bc I'm still setting some things up

outer raven
#

sorry thought it was live already!

tacit crypt
outer raven
#

aye!

#

where can we give feedback about it?

tacit crypt
tacit crypt
#

oh

#

Rodry mistyped to heck and back

outer raven
exotic leaf
ornate topaz
#

doesn't that require oauth2 for anything about nitro to be sent to you?

exotic leaf
#

Ooh thank you

exotic leaf
dawn merlin
#

I’m pretty sure the premium type is sent in the user json can’t remember

outer raven
#

logged in user ye, not external

ornate topaz
mighty bough
visual hornet
#

shallow clone probably

dawn merlin
#

pretty much, if we returned this.data, and someone modified the json from toJSON it would also modify the Embed props

copper garden
#

Wouldn't editing the fields, footer, or any property that is a ds still be affected tho?

dawn merlin
#

Yeah it’s a shallow clone not a deep one

echo laurel
#

Hello 🙂
I reinstalled my project with keeping the "discord.js": "^13.6.0" dep, but I had the bad surprise to see my code break. I then eventually figured out the cause was my ApplicationCommandOptionChoice usage (I was sending the old [string, string] array) + version update to 13.7.
So my question is about releasing : how a breaking change like this was only refered as a documentation update in the github release ?
(Or did I missed something)

Thx 🙂

copper laurel
#

Those are re-exported from an external dependency, @discord/builders which doesn't have a stable semver major release yet

echo laurel
#

Oh ok my bad I did not notice that

#

Anyway I should not have break my lock file, so it should not happen again

#

But I might set stricter dep constraints just in case

warped crater
#

hm

#

"stable semver" refers to 1.x releases. builders is at 0.x so therefore minor updates to builders can contain breaking changes - but I'm wondering how this applies to d.js re-exporting Thonk

#

in my mind this feels like it should be breaking to d.js but..

echo laurel
#
  • with locked deps it should not break often
sonic condor
#

Hi, is there a new djs version coming anytime soon which would require rewriting your bot?

real jetty
sonic condor
real jetty
#

There are no ETAs, it will be released when it's ready

sonic condor
#

Uh, alright, thanks

outer raven
#

@tacit crypt you never really suggested a better name yourself but I’m confused: do you agree with it or not?

tacit crypt
#

I agree with the PR, and if a better name can be found then even better

#

But from my pov its really not a blocker

#

or it shouldn't be I should say

outer raven
#

Alright thumbs

mighty bough
#

Why is name separate from the options argument in GuildChannelManager#create()? Why can't it be inside the object?

unique axle
#

required vs. optional

dawn merlin
#

I mean it could be in the object as a required prop

unique axle
#

that was the reasoning afaik

mighty bough
#

There are some inconsistencies for "required vs. optional" like embed footer text and client intents I'd say

dawn merlin
#

I personally would prefer it be a single object like channel.send and such shrug

vernal rose
#

There is a pr ig

mighty bough
#

I looked for one but iirc it got closed

dawn merlin
vernal rose
mighty bough
#

Alright cool, 3 approving reviews

outer raven
#

ahyes the pr with the best english

unique axle
#

they literally state that they're having issues with english in their opening post, there is absolutely no reason to bring that up again

outer raven
#

Someone could at least fix it, some sentences don’t make sense at all

raven wind
real jetty
#

Not sure if bug, but - You can send embed with empty message content, but if you have a message that has content and you try to edit it into embed, it will throw error that message content must be non-empty string

copper laurel
#

Are you trying to set content to an empty string, or to null?

copper laurel
#

Try null, on latest @dev release

real jetty
woven delta
#

Just wanted to stop by and send a big THANK YOU, from me, you guys are doing great things and made my discord dev a piece of cake
❤️

bitter peak
#

What could be causing this error? Fresh checkout of the main branch, ran yarn --immutable, yarn build, then yarn test

#

also

loud jayBOT
#

pr_open #7985 in discordjs/discord.js by memikri opened <t:1654052875:R> (review required)
feat(Client): wait for ClientReady event before resolving login
📥 npm i memikri/discord.js#feat/defer-ready-event

dawn merlin
# bitter peak also

Shouldn’t you be using the ready event to wait for ws stuff to be ready?

bitter peak
#

Well my though here is that this makes the login() method more useful, since currently it doesn't really matter too much and its return value is useless

#

This also would make it much nicer to use in a top-level-await context, for example

dawn merlin
#

But what if the client isn’t considered ready?

copper laurel
#

login and ready are not the same thing

bitter peak
#

Well that's what the PR would be solving

#

yes but I'm proposing to make them the same thing

#

I can't think of any compelling use-case where you would want to use the client when it is between logging-in and ready

copper laurel
#

I still disagree that we should abstract it away when users can promisify the ready event themselves easily anyway

ruby terrace
#

the client should be considered logged in as soon as it identifies, which is not the same thing as being ready

copper laurel
#

You can start making API calls after being logged in but before the client is ready - its just caches that aren't populated

ruby terrace
#

tbf you can make API calls without the gateway at all

copper laurel
#

Well yes, but login is the method that sets the client token

ruby terrace
#

I think you can also start sending gateway opcodes before receiving ready, though not really sure on that one

wild osprey
#

wha

dawn merlin
#

also

await client.login(process.env.DISCORD_TOKEN);
const [readyClient] = await once(client, 'ready');

console.log(`Logged in as ${readyClient.user.username}`);

Is pretty easy with TLA or an IIFE

bitter peak
dawn merlin
#

It doesn’t

bitter peak
#

(hence why I was calling its return value useless earlier)

dawn merlin
#

It returns the ready client back

#

More of type distinction but yeah

bitter peak
#

Ah got confused with login

#

Sorry

dawn merlin
#

No worries

bitter peak
#

I made the PR that added that type distinction so I should've known that one lol

white hedge
#

Is there any PR for Text in Voice?

#

I mean, for v13, not v14

real jetty
#

not yet from what i know

white hedge
ornate topaz
#

We recently landed 13.7.0, which fixed some crashes for TiV.
Creating new PRs for v13 will just push back eventual v14 release, which is starting to get slightly overdue. The hypothetical 13.8.0 would either get delayed by multitude of new PRs for backporting / adding stuff just to squish it into a release, or it would have only a fast-tracked TiV support. Doing the latter wouldn't make that much sense, as v14 already fully supports it, and the former makes entire situation worse.

neon minnow
tacit crypt
#

Thats not really useful for this channel 😒
If you have a bug report, please report it on our GitHub. If it was fixed already in a newer version, update and see if the issue still happens

neon minnow
#

But this of result of the discord.js stupid version system where next version results in lower mainaonence of older when newer is still not stable

#

And this happens over and over

nova quiver
#

v13.7 is stable

neon minnow
#

But in result of v14 development there are many features missing

nova quiver
#

thats the point of new versions they cant add everything to 1 version if they update they make new versions

#

do you understand?

opaque vessel
#

discord.js stupid version system
Yikes. It's semver dude, it's literally a standard

solemn oyster
#

Please calm down, there's no need to rant about our versioning system

nova quiver
tacit crypt
#

And sometimes maybe we do have bugs that we haven't encountered before. It happens shrug . Most helpful thing you (or anyone that encounters a bug) can do is open a GitHub issue with reproduction steps, the version you encountered the issue on and let us triage it

neon minnow
tacit crypt
#

I don't even know how you encountered that issue. Maybe your next steps should be telling us what you did / how you encountered that issue so we can look into it

nova quiver
#

maybe you don't use version 13.7

white tulip
#

I just had an idea: What if instead of the cache storing the message object, aka the object with all the helper reply functions and such, what if it'd just store the actual data, and when an event is called or someone uses cache.get or .fetch, the lib will just construct the obj then and then return it. The idea is that that'd help with saving memory

visual hornet
#

there's a tradeoff between memory and efficiency, and that seems like it would lean way too much towards the memory side and reduce efficiency

solemn oyster
#

But we won't do that way, rather, we'll have structures with a data field

ornate topaz
#

this also sounds like it would only support get or has methods, and filtering or finding would mean constructing everything

quiet viper
white tulip
#

Ah ok

solemn oyster
#

That's why we're doing a hybrid

#

So we get most of the memory benefits, without sacrificing performance

white tulip
#

How was it done before the data field?

ornate topaz
#

like it is done currently?

white tulip
#

re

#

O the properties were accessible at the top level

ornate topaz
#

wouldn't they potentially still be?

white tulip
#

Which just get from the data prop

#

I’ll check

#

Hm is it so that the prs haven’t been pushed yet

solemn oyster
#

We have an entire issue that's very elaborated on this

white tulip
#

And the interaction one

solemn oyster
#

The issue targets TSR

white tulip
solemn oyster
#

Yes

white tulip
#

Ah, I thought you meant it was done 😅

solemn oyster
#

No, TSR is coming out after v14

solemn oyster
white tulip
#

Ah TSR = Typescript rewrite

tacit crypt
#

TSR will happen sometimes after v14 btw, not necessarily a v15 (it's a massive undertaking)

stray delta
#

what reason would something be declared in BaseXChannel as opposed to XChannel?

outer raven
#

e.g. BaseTextChannel is extended by TextChannel and NewsChannel

stray delta
outer raven
full summit
#

Going to take a shot in the dark and ask here. How does one fork the main library and install from github with the new setup?

I reset a branch hard to the main lib, didn't do anything else, and it failed the 'post install' script.

Deleted that post install script from the 'scripts' in package.json and it installed but then trying to run a bot results in 'cannot find module 'discord.js'' same with 'cannot find module @discordjs/discord.js'

I am at a loss at this point on what the heck i'm supposed to do.

full summit
#

You can do one of the following solutions if you have the fork downloaded locally:

#

this doesn't help for hosted bots, unless you're assuming i have to do the same thing for each bot i host

dawn merlin
#

is your bot on a VPS?

full summit
#

i have 3, and 2 local test bots

dawn merlin
#

you can link your fork on all of the hosts

#

you'd clone your fork on the servers and then link to them

full summit
#

sounds like fun

#

So now i fall back on what the heck does it mean by
Use yarn link inside the packages/discord.js directory and in your application's folder.

#

i'm going to assume i need to create a folder and i can name it whatever the heck i want in the node_modules folder and then use link with it?

dawn merlin
#

I'm not familiar with linking in yarn, but you can have the repo cloned anywhere you just need to provide the path when linking

full summit
slate nacelle
#

In discord.js' folder you run yarn link and inside of your project's you run yarn link discord.js iirc

full summit
#

i figured it out, it was demanding a 'name' property in package.json

#

and also no

#

yarn link just posts the 'help' for link

#

and of course the link did absolutely nothing

#

This command is run in the package folder you’d like to consume. For example if you are working on react and would like to use your local version to debug a problem in react-relay, simply run yarn link inside of the react project.

Unknown Syntax Error: Not enough positional arguments.

$ yarn link [-A,--all] [-p,--private] [-r,--relative] <destination>```
#

documentation is so much fun when it's invalid

dawn merlin
#

which version of yarn are you using?

full summit
#

okay so i ran yarn link in my bot folder

#

and it worked great

dawn merlin
#

those docs apply to yarn 1.x, but in yarn 3.x, you just do yarn link [path to package]

full summit
#

so that must mean that packages/discord.js is probably already registered to some name

#

nvm it's 3.2.1

full summit
analog oyster
#

the yarn version in the discord.js repo is 3.2.1

#

but if you didnt install it in your own folders you wont have that version

full summit
#

published versions of yarn only go up to 2.4.3

#

"this project is configured to use yarn" so i forced to use yarn now am i? this is very inuitive

tacit crypt
#

The simplest way to actually get your local fork / any fork in your other repos is packing the discord.js module and installing from the pack shrug

wild flax
#

^ this pretty much

full summit
#

well then, lets see how overly complex this solution is then

#

cause so far i've hit a dead wall

full summit
#

unless i'm stupid and this isn't what you mean by 'install from pack'

tacit crypt
#

Well you'll probably also need to pack collection, install it first, then the djs pack

wild flax
#

pretty much anything that djs uses

full summit
#

it also needs rest... so i suppose i ahve to do that one as well?

#

so can i not just pack the entire project and install from it?

#

or is it literally just one by one

wild flax
#

don't think you can

full summit
#

fun

wild flax
#

pretty niche use case

#

¯_(ツ)_/¯

tacit crypt
#

I mean, unless you're trying some local changes yourself, you can just install the @dev versions of our modules

full summit
#

i have local changes

#

though i do think, if i'm especially lazy, i can just upload the tgz files to github and then install them when i pull

wild flax
#

don't we allow to configure pretty much anything already anyway

#

what is still missing people need a fork for

full summit
#

there are several changes that i have that make my life insanely easier

#

plus i've found several interesting bugs that are so much fun to diagnose

#

maybe they were already found and i needed to simply update my fork

#

but then i fall back to 'i have several changes that make my life easier'

#

also

#

installed collection

#

tried to install rest, said collection doesn't exist

#

:D

wild flax
#

yeah I honestly don't know if its even easily possible

full summit
#

that's 4 hours of my life i'm not getting back, fantastic

tacit crypt
#

Can you try it with npm instead?

full summit
#

keeps posting this error:

wild flax
#

Yeah because we use the workspace protocol

outer raven
#

If djs used yarn v1 you could link packages in the monorepo with themselves but in v3 they removed that possibility

#

Never really understood why djs moved to v3 tbh, it doesn’t give any benefit

solemn oyster
#

It does, many of them, including performance and plugins (which we use)

outer raven
#

which plugins

warped crater
#

have you thought of looking at the .yarn/plugins dir

wild flax
#

Also v1 is purely in maintenance mode lol

warped crater
#

thanks...? I was telling Rodry to have a look at it

nova quiver
#

dont worry i looked and i sent