mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-13 01:53:30 +01:00
feat: @discordjs/proxy (#7925)
Co-authored-by: Parbez <imranbarbhuiya.fsd@gmail.com>
This commit is contained in:
55
packages/proxy/src/handlers/proxyRequests.ts
Normal file
55
packages/proxy/src/handlers/proxyRequests.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { URL } from 'node:url';
|
||||
import { DiscordAPIError, HTTPError, RateLimitError, RequestMethod, REST, RouteLike } from '@discordjs/rest';
|
||||
import {
|
||||
populateAbortErrorResponse,
|
||||
populateGeneralErrorResponse,
|
||||
populateSuccessfulResponse,
|
||||
populateRatelimitErrorResponse,
|
||||
} from '../util/responseHelpers';
|
||||
import type { RequestHandler } from '../util/util';
|
||||
|
||||
/**
|
||||
* Creates an HTTP handler used to forward requests to Discord
|
||||
* @param rest REST instance to use for the requests
|
||||
*/
|
||||
export function proxyRequests(rest: REST): RequestHandler {
|
||||
return async (req, res) => {
|
||||
const { method, url } = req;
|
||||
|
||||
if (!method || !url) {
|
||||
throw new TypeError(
|
||||
'Invalid request. Missing method and/or url, implying that this is not a Server IncomingMesage',
|
||||
);
|
||||
}
|
||||
|
||||
// The 2nd parameter is here so the URL constructor doesn't complain about an "invalid url" when the origin is missing
|
||||
// we don't actually care about the origin and the value passed is irrelevant
|
||||
const fullRoute = new URL(url, 'http://noop').pathname.replace(/^\/api(\/v\d+)?/, '') as RouteLike;
|
||||
|
||||
try {
|
||||
const discordResponse = await rest.raw({
|
||||
body: req,
|
||||
fullRoute,
|
||||
// This type cast is technically incorrect, but we want Discord to throw Method Not Allowed for us
|
||||
method: method as RequestMethod,
|
||||
passThroughBody: true,
|
||||
});
|
||||
|
||||
await populateSuccessfulResponse(res, discordResponse);
|
||||
} catch (error) {
|
||||
if (error instanceof DiscordAPIError || error instanceof HTTPError) {
|
||||
populateGeneralErrorResponse(res, error);
|
||||
} else if (error instanceof RateLimitError) {
|
||||
populateRatelimitErrorResponse(res, error);
|
||||
} else if (error instanceof Error && error.name === 'AbortError') {
|
||||
populateAbortErrorResponse(res);
|
||||
} else {
|
||||
// Unclear if there's better course of action here for unknown erorrs. Any web framework allows to pass in an error handler for something like this
|
||||
// at which point the user could dictate what to do with the error - otherwise we could just 500
|
||||
throw error;
|
||||
}
|
||||
} finally {
|
||||
res.end();
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user