mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-11 17:13:31 +01:00
* docs: fix typos * indicies -> indices * rename file --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { URL } from 'node:url';
|
|
import {
|
|
DiscordAPIError,
|
|
HTTPError,
|
|
RateLimitError,
|
|
type RequestMethod,
|
|
type REST,
|
|
type RouteLike,
|
|
} from '@discordjs/rest';
|
|
import {
|
|
populateAbortErrorResponse,
|
|
populateGeneralErrorResponse,
|
|
populateSuccessfulResponse,
|
|
populateRatelimitErrorResponse,
|
|
} from '../util/responseHelpers.js';
|
|
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 IncomingMessage',
|
|
);
|
|
}
|
|
|
|
// 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 parsedUrl = new URL(url, 'http://noop');
|
|
// eslint-disable-next-line unicorn/no-unsafe-regex, prefer-named-capture-group
|
|
const fullRoute = parsedUrl.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,
|
|
query: parsedUrl.searchParams,
|
|
headers: {
|
|
'Content-Type': req.headers['content-type']!,
|
|
},
|
|
});
|
|
|
|
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 errors. 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();
|
|
}
|
|
};
|
|
}
|