fnbr
Version:
A library to interact with Epic Games' Fortnite HTTP and XMPP services
124 lines • 6.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const axios_1 = tslib_1.__importStar(require("axios"));
const Base_1 = tslib_1.__importDefault(require("../Base"));
const AuthenticationMissingError_1 = tslib_1.__importDefault(require("../exceptions/AuthenticationMissingError"));
const constants_1 = require("../../resources/constants");
const EpicgamesAPIError_1 = tslib_1.__importDefault(require("../exceptions/EpicgamesAPIError"));
/**
* Represents the client's HTTP manager
* @private
*/
class HTTP extends Base_1.default {
/**
* @param client The main client
*/
constructor(client) {
super(client);
this.axios = axios_1.default.create({
...this.client.config.http,
headers: {
'Content-Type': null,
...this.client.config.http.headers,
},
});
// Clear all default content type headers
Object.keys(this.axios.defaults.headers).forEach((h) => {
var _a;
(_a = this.axios.defaults.headers[h]) === null || _a === void 0 ? true : delete _a['Content-Type'];
});
}
/**
* Sends an HTTP request
* @param config The request config
* @param auth The auth session to use
* @param retries How many times this request has been retried (5xx errors)
*/
async request(config, retries = 0) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
const reqStartTime = Date.now();
try {
const response = await this.axios.request({
...config,
headers: {
'Accept-Language': this.client.config.language,
...config.headers,
},
});
const reqDuration = ((Date.now() - reqStartTime) / 1000);
this.client.debug(`${(_b = (_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) !== null && _b !== void 0 ? _b : 'GET'} ${config.url} (${reqDuration.toFixed(2)}s): `
+ `${response.status} ${response.statusText}`, 'http');
return response.data;
}
catch (err) {
const reqDuration = ((Date.now() - reqStartTime) / 1000);
if (err instanceof axios_1.AxiosError) {
const errResponse = err.response;
const errResponseData = errResponse === null || errResponse === void 0 ? void 0 : errResponse.data;
this.client.debug(`${(_d = (_c = config.method) === null || _c === void 0 ? void 0 : _c.toUpperCase()) !== null && _d !== void 0 ? _d : 'GET'} ${config.url} (${reqDuration.toFixed(2)}s): `
+ `${errResponse === null || errResponse === void 0 ? void 0 : errResponse.status} ${errResponse === null || errResponse === void 0 ? void 0 : errResponse.statusText}`, 'http');
if ((errResponse === null || errResponse === void 0 ? void 0 : errResponse.status.toString().startsWith('5')) && retries < this.client.config.restRetryLimit) {
return this.request(config, retries + 1);
}
if (errResponse && (errResponse.status === 429 || (errResponseData === null || errResponseData === void 0 ? void 0 : errResponseData.errorCode) === 'errors.com.epicgames.common.throttled')) {
const retryString = errResponse.headers['retry-after']
|| ((_e = errResponseData === null || errResponseData === void 0 ? void 0 : errResponseData.messageVars) === null || _e === void 0 ? void 0 : _e[0])
|| ((_g = (_f = errResponseData === null || errResponseData === void 0 ? void 0 : errResponseData.errorMessage) === null || _f === void 0 ? void 0 : _f.match(/(?<=in )\d+(?= second)/)) === null || _g === void 0 ? void 0 : _g[0]);
const retryAfter = parseInt(retryString, 10);
if (!Number.isNaN(retryAfter)) {
const sleepTimeout = (retryAfter * 1000) + 500;
await new Promise((res) => setTimeout(res, sleepTimeout));
return this.request(config, retries);
}
}
}
else {
this.client.debug(`${(_j = (_h = config.method) === null || _h === void 0 ? void 0 : _h.toUpperCase()) !== null && _j !== void 0 ? _j : 'GET'} ${config.url} `
+ `(${reqDuration.toFixed(2)}s): ${err.name} - ${err.message}`, 'http');
}
throw err;
}
}
/**
* Sends an HTTP request to the Fortnite API
* @param config The request config
* @param includeAuthentication Whether to include authentication
* @throws {EpicgamesAPIError}
* @throws {AxiosError}
*/
async epicgamesRequest(config, auth) {
var _a, _b, _c, _d;
if (auth) {
const authSession = this.client.auth.sessions.get(auth);
if (!authSession)
throw new AuthenticationMissingError_1.default(auth);
await authSession.refreshLock.wait();
}
try {
return await this.request({
...config,
...auth && {
headers: {
...config.headers,
Authorization: `bearer ${this.client.auth.sessions.get(auth).accessToken}`,
},
},
});
}
catch (err) {
if (err instanceof axios_1.AxiosError) {
if (auth && constants_1.invalidTokenCodes.includes((_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errorCode)) {
await this.client.auth.sessions.get(auth).refresh();
return this.epicgamesRequest(config, auth);
}
if (typeof ((_d = (_c = err.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.errorCode) === 'string') {
throw new EpicgamesAPIError_1.default(err.response.data, config, err.response.status);
}
}
throw err;
}
}
}
exports.default = HTTP;
//# sourceMappingURL=HTTP.js.map