function sendRequest()

in authui-container/src/utils/http-client.ts [101:175]


function sendRequest(config: HttpRequestConfig): Promise<LowLevelResponse> {
  let actualResponse: Response;
  let url = config.url;
  // Edge pre-chromium throws when undefined is provided.
  const headers = new Headers(config.headers || {});
  let contentType = headers.get('content-type');
  let body: string;

  if (config.data) {
    if (config.method === 'GET' || config.method === 'HEAD') {
      if (!isNonNullObject(config.data)) {
        return Promise.reject(new Error(`${config.method} requests cannot have a body.`));
      }
      // Parse URL and append data to query string.
      const parsedUrl = new URL(config.url);
      const dataObj = config.data as {[key: string]: string};
      for (const key in dataObj) {
        if (dataObj.hasOwnProperty(key)) {
          parsedUrl.searchParams.append(key, dataObj[key]);
        }
      }
      url = parsedUrl.toString();
    } else if (contentType &&
               contentType.toLowerCase().includes('application/x-www-form-urlencoded')) {
      // Prefer not to use FormData as it automatically sets the Content-Type to multipart/form-data.
      // https://github.com/github/fetch/issues/263.
      body = Object.keys(config.data).map((key) => {
        return encodeURIComponent(key) + '=' + encodeURIComponent(config.data[key]);
      }).join('&');
    } else {
      body = JSON.stringify(config.data);
    }
  }

  const request: RequestInit = removeUndefinedFields({
    method: config.method,
    mode: config.mode,
    cache: config.cache,
    headers: config.headers,
    credentials: config.credentials,
    body,
  });

  return new Promise<LowLevelResponse>((resolve, reject) => {
    let timeoutId: number;
    if (config.timeout) {
      timeoutId = window.setTimeout(() => {
        reject(new Error(`Error while making request: timeout of ${config.timeout}ms exceeded`));
      }, config.timeout);
    }
    return fetch(url, request)
      .then((response: Response) => {
        window.clearTimeout(timeoutId);
        actualResponse = response;
        contentType = response.headers.get('content-type');
        if (contentType && contentType.toLowerCase().includes('application/json')) {
          return response.json();
        }
        return response.text();
      })
      .then((jsonResponse: object | string) => {
        resolve({
          status: actualResponse.status,
          headers: actualResponse.headers,
          config,
          request,
          data: jsonResponse,
        });
      })
      .catch((error: Error) => {
        window.clearTimeout(timeoutId);
        reject(error);
      });
  });
}