dressed
Version:
A sleek, serverless-ready Discord bot framework.
81 lines • 3.92 kB
JavaScript
import { Buffer } from "node:buffer";
import { RouteBases } from "discord-api-types/v10";
import { botEnv, serverConfig } from "./env.js";
import { logError } from "./log.js";
import { checkLimit } from "./ratelimit.js";
export async function callDiscord(endpoint, init, $req = {}) {
var _a, _b, _c, _d, _e, _f, _g, _h;
const { params, files, flattenBodyInForm, ...options } = { ...init };
const reqsConfig = serverConfig.requests;
const { authorization = (_a = reqsConfig === null || reqsConfig === void 0 ? void 0 : reqsConfig.authorization) !== null && _a !== void 0 ? _a : `Bot ${(_c = (_b = $req.env) === null || _b === void 0 ? void 0 : _b.DISCORD_TOKEN) !== null && _c !== void 0 ? _c : botEnv.DISCORD_TOKEN}`, tries = (_d = reqsConfig === null || reqsConfig === void 0 ? void 0 : reqsConfig.tries) !== null && _d !== void 0 ? _d : 3, routeBase = (_e = reqsConfig === null || reqsConfig === void 0 ? void 0 : reqsConfig.routeBase) !== null && _e !== void 0 ? _e : RouteBases.api, bucketTTL = (_f = reqsConfig === null || reqsConfig === void 0 ? void 0 : reqsConfig.bucketTTL) !== null && _f !== void 0 ? _f : 30 * 60, } = $req;
const url = new URL(routeBase + endpoint);
if (typeof options.body === "object" && options.body !== null) {
if ("files" in options.body)
delete options.body.files;
if ("file" in options.body)
delete options.body.file;
}
if (params) {
for (const [key, value] of Object.entries(params)) {
if (!value)
continue;
url.searchParams.append(key, typeof value === "string" ? value : JSON.stringify(value));
}
}
if (files === null || files === void 0 ? void 0 : files.length) {
const formData = new FormData();
for (const [index, file] of files.entries()) {
const fileKey = (_g = file.key) !== null && _g !== void 0 ? _g : `files[${index}]`;
formData.append(fileKey, new Blob([Buffer.isBuffer(file.data) ? Buffer.from(file.data) : file.data.toString()], {
type: file.contentType,
}), file.name);
}
if (options.body && flattenBodyInForm) {
for (const [key, value] of Object.entries(options.body)) {
formData.append(key, value);
}
}
else if (options.body) {
formData.append("payload_json", JSON.stringify(options.body));
}
options.body = formData;
}
else if (options.body) {
options.body = JSON.stringify(options.body);
}
const req = new Request(url, {
headers: { authorization, ...(!(files === null || files === void 0 ? void 0 : files.length) ? { "content-type": "application/json" } : {}) },
...options,
});
const updateLimit = await checkLimit(req, bucketTTL);
const res = await fetch(req);
updateLimit(res);
if (!res.ok) {
if (res.status === 429 && tries > 0) {
$req.tries = tries - 1;
return callDiscord(endpoint, init, $req);
}
const error = (await res.json());
logError(`${error.message} (${(_h = error.code) !== null && _h !== void 0 ? _h : res.status})`);
if (error.errors)
logErrorData(error.errors);
throw new Error(`Failed to ${options.method} ${endpoint} (${res.status})`, { cause: res });
}
return res;
}
function logErrorData(data, path = []) {
if (typeof data === "string") {
console.error(`${path.join(".")}: ${data}`);
}
else if ("_errors" in data && Array.isArray(data._errors)) {
for (const err of data._errors) {
logErrorData(err, path);
}
}
else if (typeof data === "object" && data !== null) {
for (const [key, value] of Object.entries(data)) {
logErrorData(value, [...path, key]);
}
}
}
//# sourceMappingURL=call-discord.js.map