UNPKG

@translated/lara

Version:

Official Lara SDK for JavaScript and Node.js

230 lines (229 loc) 8.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BrowserClient = exports.BrowserLaraClient = void 0; const errors_1 = require("../../errors"); const client_1 = require("./client"); function hasDefaultPort(port, secure) { return (port === 80 && !secure) || (port === 443 && secure); } /** @internal */ class BrowserLaraClient extends client_1.LaraClient { constructor(baseUrl, auth, _keepAlive, timeout) { super(auth); let url = `${baseUrl.secure ? "https" : "http"}://${baseUrl.hostname}`; if (!hasDefaultPort(baseUrl.port, baseUrl.secure)) url += `:${baseUrl.port}`; this.baseUrl = url; this.timeout = timeout; } async send(method, path, headers, body, streamResponse) { var _a; let requestBody; if (body) { if (headers["Content-Type"] === "multipart/form-data") { delete headers["Content-Type"]; // browser will set it automatically const formBody = new FormData(); for (const [key, value] of Object.entries(body)) { if (!value) continue; if (Array.isArray(value)) { for (const v of value) formBody.append(key, v); } else { formBody.append(key, value); } } requestBody = formBody; } else { requestBody = JSON.stringify(body, undefined, 0); } } const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined; try { const response = await fetch(this.baseUrl + path, { headers, method, body: requestBody, signal }); if (streamResponse && response.status >= 200 && response.status < 300) { return { statusCode: response.status, body: response.body, headers: Object.fromEntries(response.headers) }; } if ((_a = response.headers.get("Content-Type")) === null || _a === void 0 ? void 0 : _a.includes("text/csv")) { return { statusCode: response.status, body: { content: await response.text() }, headers: Object.fromEntries(response.headers) }; } return { statusCode: response.status, body: await response.json(), headers: Object.fromEntries(response.headers) }; } catch (err) { if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) { throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`); } throw err; } } async *sendAndGetStream(method, path, headers, body) { let requestBody; if (body) { if (headers["Content-Type"] === "multipart/form-data") { delete headers["Content-Type"]; // browser will set it automatically const formBody = new FormData(); for (const [key, value] of Object.entries(body)) { if (!value) continue; if (Array.isArray(value)) { for (const v of value) formBody.append(key, v); } else { formBody.append(key, value); } } requestBody = formBody; } else { requestBody = JSON.stringify(body, undefined, 0); } } const signal = this.timeout && this.timeout > 0 ? AbortSignal.timeout(this.timeout) : undefined; let response; try { response = await fetch(this.baseUrl + path, { headers, method, body: requestBody, signal }); } catch (err) { if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) { throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`); } throw err; } if (!response.body) { throw new Error("Response body is not available for streaming"); } const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; try { while (true) { let readResult; try { readResult = await reader.read(); } catch (err) { if (err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError")) { throw new errors_1.TimeoutError(`Request timed out after ${this.timeout}ms`); } throw err; } const { done, value } = readResult; if (done) { // Process any remaining data in buffer if (buffer.trim()) { try { const json = JSON.parse(buffer); yield { statusCode: json.status || response.status, body: json.data || json, headers: Object.fromEntries(response.headers) }; } catch (_e) { // Skip invalid JSON } } break; } buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop() || ""; // Keep incomplete line in buffer for (const line of lines) { if (line.trim()) { try { const json = JSON.parse(line); yield { statusCode: json.status || response.status, body: json.data || json, headers: Object.fromEntries(response.headers) }; } catch (_e) { // Skip invalid JSON lines } } } } } finally { reader.releaseLock(); } } wrapMultiPartFile(file) { if (file instanceof File) return file; throw new TypeError(`Invalid file input in the browser. Expected an instance of File but received ${typeof file}.`); } } exports.BrowserLaraClient = BrowserLaraClient; // biome-ignore lint/complexity/noStaticOnlyClass: used as a namespace for HTTP client methods class BrowserClient { static async get(url, headers) { return BrowserClient.send("GET", url, headers); } static async send(method, url, headers, body) { var _a; let requestBody; if (body) { if (headers && headers["Content-Type"] === "multipart/form-data") { delete headers["Content-Type"]; // browser will set it automatically const formBody = new FormData(); for (const [key, value] of Object.entries(body)) { if (!value) continue; if (Array.isArray(value)) { for (const v of value) formBody.append(key, v); } else { formBody.append(key, value); } } requestBody = formBody; } else { requestBody = JSON.stringify(body, undefined, 0); } } const response = await fetch(url, { headers, method, body: requestBody }); return { statusCode: response.status, headers: Object.fromEntries(response.headers), body: ((_a = response.headers.get("Content-Type")) === null || _a === void 0 ? void 0 : _a.includes("application/json")) ? await response.json() : await response.text() }; } } exports.BrowserClient = BrowserClient;