const UserAgentManager = require('./UserAgentManager'); const RESTMethods = require('./RESTMethods'); const SequentialRequestHandler = require('./RequestHandlers/Sequential'); const BurstRequestHandler = require('./RequestHandlers/Burst'); const APIRequest = require('./APIRequest'); const Constants = require('../../util/Constants'); class RESTManager { constructor(client) { this.client = client; this.handlers = {}; this.userAgentManager = new UserAgentManager(this); this.methods = new RESTMethods(this); this.rateLimitedEndpoints = {}; this.globallyRateLimited = false; } destroy() { for (const handlerKey of Object.keys(this.handlers)) { const handler = this.handlers[handlerKey]; if (handler.destroy) handler.destroy(); } } push(handler, apiRequest) { // Preserve async stack let stackTrace = null; if (Error.captureStackTrace) { stackTrace = {}; Error.captureStackTrace(stackTrace, this.makeRequest); } return new Promise((resolve, reject) => { handler.push({ request: apiRequest, resolve, reject: error => { if (stackTrace && (error instanceof Error)) { stackTrace.name = error.name; stackTrace.message = error.message; error.stack = stackTrace.stack; } reject(error); }, retries: 0, }); }); } getRequestHandler() { switch (this.client.options.apiRequestMethod) { case 'sequential': return SequentialRequestHandler; case 'burst': return BurstRequestHandler; default: throw new Error(Constants.Errors.INVALID_RATE_LIMIT_METHOD); } } makeRequest(method, url, auth, data, file, reason) { const apiRequest = new APIRequest(this, method, url, auth, data, file, reason); if (!this.handlers[apiRequest.route]) { const RequestHandlerType = this.getRequestHandler(); this.handlers[apiRequest.route] = new RequestHandlerType(this, apiRequest.route); } return this.push(this.handlers[apiRequest.route], apiRequest); } } module.exports = RESTManager;