UNPKG

@scalar/api-client

Version:

the open source API testing client

127 lines (125 loc) 5.28 kB
import { ERRORS as P, normalizeError as U } from "../errors.js"; import { normalizeHeaders as N } from "../normalize-headers.js"; import { createFetchBody as Z } from "./create-fetch-body.js"; import { createFetchHeaders as $ } from "./create-fetch-headers.js"; import { createFetchQueryParams as M } from "./create-fetch-query-params.js"; import { decodeBuffer as ee } from "./decode-buffer.js"; import { setRequestCookies as oe, getCookieHeader as te } from "./set-request-cookies.js"; import { replaceTemplateVariables as h } from "../string-template.js"; import { isElectron as q } from "../electron.js"; import { isDefined as re, mergeUrls as se, shouldUseProxy as D, redirectToProxy as ne, httpStatusCodes as ae } from "@scalar/oas-utils/helpers"; import { buildRequestSecurity as ie } from "./build-request-security.js"; const Ce = ({ environment: E, example: a, globalCookies: L, proxyUrl: u, request: i, securitySchemes: z, selectedSecuritySchemeUids: B = [], server: d, status: o, pluginManager: f }) => { try { const t = E ?? {}, w = new AbortController(), R = a.parameters.path.reduce((e, s) => (s.enabled && (e[s.key] = h(s.value, t)), e), {}), F = h((d == null ? void 0 : d.url) ?? "", t), p = h(h(i.path, t), R); let n = F || p; if (!n) throw P.URL_EMPTY; Object.entries((d == null ? void 0 : d.variables) ?? {}).forEach(([e, s]) => { n = h(n, { [e]: R[e] || s.default }); }); const _ = M(a, t, i), O = $(a, t), { body: W } = Z(i.method, a, t), { cookieParams: x } = oe({ example: a, env: t, globalCookies: L, serverUrl: n, proxyUrl: u }), A = B.flat().map((e) => z[e]).filter(re), S = ie(A, t), c = { ...Object.entries(S.headers).reduce( (e, [s, y]) => (e[s.toLowerCase()] = y, e), {} ), ...O }, X = [...x, ...S.cookies], j = new URLSearchParams([..._, ...S.urlParams]); q() && c["user-agent"] && (c["X-Scalar-User-Agent"] = c["user-agent"]), n = se(n, p, j); const k = h(te(X, c.Cookie), t); k && (q() || D(u, n) ? (console.warn( "We're using a `X-Scalar-Cookie` custom header to the request. The proxy will forward this as a `Cookie` header. We do this to avoid the browser omitting the `Cookie` header for cross-origin requests for security reasons." ), c["X-Scalar-Cookie"] = k) : (console.warn( `We're trying to add a Cookie header, but browsers often omit them for cross-origin requests for various security reasons. If it's not working, that's probably why. Here are the requirements for it to work: - The browser URL must be on the same domain as the server URL. - The connection must be made over HTTPS. ` ), c.Cookie = k)); const I = ne(u, n), b = new Request(I, { method: i.method.toUpperCase(), body: W ?? null, headers: c }); return [ null, { request: b, sendRequest: async () => { var s, y, C; o == null || o.emit("start"), f && f.executeHook("onBeforeRequest", { request: b }); const e = Date.now(); try { const r = await fetch(b, { signal: w.signal }), Q = (s = r.headers.get("content-type")) == null ? void 0 : s.startsWith("text/event-stream"); o == null || o.emit("stop"); const V = Date.now() - e, v = r.clone(), g = N(r.headers, D(u, n)), K = r.headers.get("content-type") ?? "text/plain;charset=UTF-8", T = await v.arrayBuffer(), Y = ee(T, K), m = r.clone(), G = m.statusText || ((y = ae[m.status]) == null ? void 0 : y.name) || "", J = [204, 205, 304].includes(m.status), l = new Response(J ? null : m.body, { status: m.status, statusText: G, headers: m.headers }); f && f.executeHook("onResponseReceived", { response: l, operation: i }); const H = "getSetCookie" in l.headers && typeof l.headers.getSetCookie == "function" ? l.headers.getSetCookie() : []; return Q && r.body ? [ null, { timestamp: Date.now(), request: a, response: { ...l, headers: g, cookieHeaderKeys: H, reader: (C = r.body) == null ? void 0 : C.getReader(), duration: V, method: i.method, path: p } } ] : [ null, { timestamp: Date.now(), request: a, response: { ...r, headers: g, cookieHeaderKeys: H, data: Y, size: T.byteLength, duration: Date.now() - e, method: i.method, status: r.status, path: p } } ]; } catch (r) { return o == null || o.emit("abort"), [U(r, P.REQUEST_FAILED), null]; } }, controller: w } ]; } catch (t) { return console.error(t), o == null || o.emit("abort"), [U(t), null]; } }; export { Ce as createRequestOperation };