-
-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: node-fetch & @discordjs/formdata -> undici #6586
Conversation
https://github.com/nodejs/undici#undicifetchinput-init-promise
https://nodejs.org/api/documentation.html#documentation_stability_index
|
I completely agree with this not being ready yet, just posting it here for some discussion. I assume most of the animosity in the previous discussion linked above was that someone had to do the work, so I decided to just see what happens. Although I believe v16 is about to be LTS which should mean that both Blob and web streams should be removed from experimental status (?). edit: pretty sure this library also requires v16+ (or at least v15) to use AbortController anyways. |
EDIT: the reply was deleted
I've never personally used
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite the comment above, I'm okay with the overall change once we know the stability will not be 1
in Node 16 LTS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use axios though?
Adding to the arguments given above
- Axios also has a known bug in that you cannot send a
body
when sending a DELETE request. Axios is currently still onI have been corrected, apparently Axios doesn't use semver but 0ver. If you treasure your sanity, do not open that URL.0.x
which per strict semver means "initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable" (source). Therefore Axios should not be considered stable to begin with. Hardly a library we can afford to have in a project as large and with as many users as DiscordJS.- Axios has a backlog of issues and open pull requests from here to Saturn. If, aside from point 1, we'd ever run into an issue then the likelihood of having to just fork it and publish @discordjs/axios would be extremely large because likewise the likelihood of them merging a PR and releasing that in a timely fashion is extremely small.
From unidici's readme:
will this be an issue? |
In some cases, I believe so:
I can add in a utility to consume the body in these cases if you'd like. edit: due to it being an issue with node's gc, wouldn't this also affect node-fetch as well? |
discord.js/src/rest/APIRequest.js Line 53 in 72e3958
|
Can |
Using undici is really living on the edge of experimental apis...
So no... you can't append a buffer into their FormData instance, you have to construct a File using there version of the File implementation. (or creating a Blob using node:buffer - that later gets upgraded by their FormData impl automatically according to spec) About Blobs...One of the reason why fetch-blob haven't switched to using the built in version of NodeJS Blob impl is b/c they are pretty darn useless unless you can't get them backed up by the filesystem somehow, otherwise they are just useless containers that stores a buffers in memory where you could as well use a uint8array or ArrayBuffer directly instead. With Only then when File and blobs backed up by the file system would we over at node-fetch start to consider using the built in impl. and marking fetch-blob as legacy. cuz right now it serves a purpose not even NodeJS have fixed in their version. About FormDataNow to the version of undici FormData impl... knowing what i have written earlier about node's wortless Blob container and how strict undici FormData only accept a version of NodeJS own Blob implementation... Unlike one other spec compatible FormData implementations such as formdata-polyfill it dose not use instanceof checks. It can work with other Blob/File implementations as long as they look like a Blob, so it can accept both a fetch-blob and a NodeJS blob and it can generate a FormData boundary/payload without ever reading the files content. undici is more focused on writing something they wish to see being implemented into core one day. not something that is best suitable for userland as they require the latest experimental features if i would choose between undici and node-fetch then i would maybe go with node-fetch 2.x or 3.x b/c it's
|
The issues you brought up are completely out of scope for this repo and mostly don't apply (either to the platform, usage, or users). |
The Neither of them returns I did some tinkering and got the
static async resolveFile(resource) {
if (typeof resource === 'string') {
if (/^https?:\/\//.test(resource)) {
const res = await fetch(resource);
// return res.body;
return res.blob();
}
// ...
}
}
static async resolveFile(resource) {
if (typeof resource === 'string') {
// ...
return new Promise((resolve, reject) => {
const file = path.resolve(resource);
fs.stat(file, (err, stats) => {
if (err) return reject(err);
if (!stats.isFile()) return reject(new DiscordError('FILE_NOT_FOUND', file));
return fs.readFile(file, (error, buf) => {
if (error) return reject(error);
return resolve(buf);
});
});
});
}
}
|
I got everything fixed & tested with both In |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works fine. Make sure to update the typings too:
Line 628 in fe95005
public static resolveFile(resource: BufferResolvable | Stream): Promise<Buffer | Stream>; |
I think this PR should be classified as
|
This needs a rebase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fix lint
guess the precommit hook wasn't working, thought it would have caught that for me 😕 |
@kyranet buffer.Blob still remains |
I was slightly off with this one, by about 1 LTS version, but v18 will have a global Blob and experimental status removed as well :) |
hey 😏 |
allow Blob in MessageAttachment and fix sending files
I have no interest in keeping this PR open as it likely won't land. |
I know this was closed but undici's fetch just landed on node as an experimental flag, so now is an even better time to reopen this PR IMO |
This was closed because it's going to be added to /rest now. Also there's a roadblock in mocking some of the request data. |
This was closed because the author didn't feel like keeping it up. There's no open issue about that to my knowledge |
I've spoken to the author and my reasons for why it's closed are from what they told me. |
How could you even reopen this PR? The majority of the point of the PR has been made obsolete because /rest has already replaced it. As you've already been told, the author was told the switch to /rest was happening soon and thus this probably couldn't land. Between me and the author we are looking to make this PR a reality in /rest but switching the tests over is a major rewrite and since there are still things that are experimental in undici fetch we aren't rushing to do that. |
Please describe the changes this PR makes and why it should be merged:
Removed the dependencies of
node-fetch
and@discordjs/formdata
in favor ofundici
.Undici contains spec-compliant
fetch
andFormData
implementations, is maintained byNodeJS contributors, and is just basically all around better. Repo
Complete list of changes:
@discordjs/form-data
package and its 4 dependencies.node-fetch
(still installed as a dev package)Blob
parameter.Blob
now, whereas it used to return aBuffer
orReadableStream
.Promise<string>
.edit: I've been personally using this on my bot (roughly 21,000 members) that has made thousands of http requests and there has been no issue. This PR is likely ready for production use if anyone reading this wants to try it out. ;)
Status and versioning classification: