async request(call, data, method = "GET", req = {}) {
      var _response;

      req = Object.assign({}, req); // clone

      req.method = req.method || method;
      req.responseType = req.responseType || "json";
      req.headers = Object.assign({
        "Content-Type": "application/json; charset=utf-8"
      }, req.headers || {});

      if (this.isAuthenticated()) {
        req.headers["Authorization"] = req.headers["Authorization"] || "Bearer ".concat(this.accessToken);
      }

      req.body = data;
      call = new URL(call, this.constructor.apiDomain); // Prevent getting a cached response. Cache-control is often not allowed via CORS

      if (req.method == "GET" && this.constructor.useCache !== false) {
        call.searchParams.set("timestamp", Date.now());
      }

      if ($.type(req.body) === "object") {
        if (req.method === "GET" || req.method === "HEAD") {
          for (let p in req.body) {
            let action = req.body[p] === undefined ? "delete" : "set";
            call.searchParams[action](p, req.body[p]);
          }

          delete req.body;
        } else {
          req.body = JSON.stringify(req.body);
        }
      }

      let response;

      try {
        response = await fetch(call, req);
      } catch (err) {
        this.mavo.error("Something went wrong while connecting to " + this.id, err);
      }

      if ((_response = response) !== null && _response !== void 0 && _response.ok) {
        if (req.method === "HEAD" || req.responseType === "response") {
          return response;
        } else {
          return response[req.responseType]();
        }
      } else {
        throw response;
      }
    }
Helper for making OAuth requests with JSON-based APIs.