All files / api http.js

92.68% Statements 38/41
89.18% Branches 33/37
66.66% Functions 4/6
97.43% Lines 38/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 934x     23x   23x 23x       23x     23x 23x       23x 23x   23x 22x     1x       23x   23x 1x     22x       23x 23x 23x 23x 23x   23x         23x           23x 8x     23x 6x 6x     23x 23x 23x 23x   23x 23x 23x   1x       23x                     23x      
const DEFAULT_TIMEOUT_MS = Number(import.meta.env.VITE_API_TIMEOUT_MS || 10000);
 
function buildQuery(params) {
  const query = new URLSearchParams();
 
  for (const [key, value] of Object.entries(params || {})) {
    Iif (value === undefined || value === null) {
      continue;
    }
 
    query.append(key, String(value));
  }
 
  const serialized = query.toString();
  return serialized ? `?${serialized}` : "";
}
 
function joinUrl(baseUrl, path) {
  const base = String(baseUrl || "").replace(/\/+$/, "");
  const nextPath = String(path || "").replace(/^\/+/, "");
 
  if (!base) {
    return `/${nextPath}`;
  }
 
  return `${base}/${nextPath}`;
}
 
function wrapProxyPath(path, query) {
  const proxyPath = import.meta.env.VITE_API_PROXY_PATH || "";
 
  if (!proxyPath) {
    return `${path}${buildQuery(query)}`;
  }
 
  return `${proxyPath}${buildQuery({ path, ...(query || {}) })}`;
}
 
export async function requestHttp(method, path, body, options = {}) {
  const timeoutMs = Number(options.timeoutMs || DEFAULT_TIMEOUT_MS);
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
  const baseUrl = import.meta.env.VITE_API_BASE_URL || "";
  const url = joinUrl(baseUrl, wrapProxyPath(path, options.query));
 
  const headers = {
    Accept: "application/json",
    ...(options.headers || {}),
  };
 
  const init = {
    method,
    headers,
    signal: controller.signal,
  };
 
  if (options.signal) {
    options.signal.addEventListener("abort", () => controller.abort(), { once: true });
  }
 
  if (body !== undefined && body !== null) {
    headers["Content-Type"] = "application/json";
    init.body = JSON.stringify(body);
  }
 
  try {
    const response = await fetch(url, init);
    const text = await response.text();
    let data = text;
 
    Eif (text) {
      try {
        data = JSON.parse(text);
      } catch (_) {
        data = text;
      }
    }
 
    return {
      response,
      data,
      meta: {
        url,
        method,
        statusCode: response.status,
        headers: response.headers,
      },
    };
  } finally {
    clearTimeout(timeout);
  }
}