UNPKG

@freemework/common

Version:

Common library of the Freemework Project.

160 lines 6.51 kB
import { FDisposableBase } from "../lifecycle/index.js"; import { FHttpClient } from "./f_http_client.js"; import { FLimit } from "../limit/f_limit.js"; import { FCancellationExecutionContext } from "../cancellation/index.js"; import { FLimitInMemory } from "../limit/f_limit_in_memory.js"; import * as querystring from "querystring"; export class FWebClient extends FDisposableBase { _baseUrl; _userAgent; _httpClient; _limitHandle; constructor(url, opts) { super(); this._baseUrl = typeof url === "string" ? new URL(url) : url; if (opts !== undefined) { const { limit, httpClient, userAgent } = opts; if (limit !== undefined) { this._limitHandle = FLimit.isLimitOpts(limit.instance) ? { instance: new FLimitInMemory(limit.instance), isOwnInstance: true, timeout: limit.timeout } : { instance: limit.instance, isOwnInstance: false, timeout: limit.timeout }; } if (httpClient !== undefined) { if ("invoke" in httpClient) { this._httpClient = httpClient; } else { this._httpClient = new FHttpClient({ ...httpClient }); } } else { this._httpClient = new FHttpClient(); } if (userAgent !== undefined) { this._userAgent = userAgent; } } else { this._httpClient = new FHttpClient(); } } get(executionContext, urlPath, opts) { super.verifyNotDisposed(); const { queryArgs = undefined, headers = undefined, limitWeight = undefined } = (() => opts || {})(); const path = queryArgs !== undefined ? urlPath + "?" + querystring.stringify(queryArgs) : urlPath; return this.invoke(executionContext, path, "GET", { headers: headers, limitWeight: limitWeight }); } postJson(executionContext, urlPath, opts) { // Serialize JSON if body is object const friendlyBody = Buffer.from(JSON.stringify(opts.postData)); const friendlyHeaders = opts.headers !== undefined ? { ...opts.headers } : {}; if (!("Content-Type" in friendlyHeaders)) { friendlyHeaders["Content-Type"] = "application/json"; } friendlyHeaders["Content-Length"] = friendlyBody.byteLength; return this.invoke(executionContext, urlPath, "POST", { headers: friendlyHeaders, body: friendlyBody }); } postForm(executionContext, urlPath, opts) { super.verifyNotDisposed(); const { postArgs = undefined, headers = undefined, limitWeight = undefined } = (() => opts || {})(); const bodyStr = postArgs && querystring.stringify(postArgs); const { body, bodyLength } = (() => { if (bodyStr !== undefined) { const bodyBuffer = Buffer.from(bodyStr); return { body: bodyBuffer, bodyLength: bodyBuffer.byteLength }; } else { return { body: undefined, bodyLength: 0 }; } })(); const friendlyHeaders = (() => { const baseHeaders = { "Content-Type": "application/x-www-form-urlencoded", "Content-Length": bodyLength }; return headers !== undefined ? { ...baseHeaders, ...headers } : baseHeaders; })(); return this.invoke(executionContext, urlPath, "POST", { body: body, headers: friendlyHeaders, limitWeight: limitWeight }); } async invoke(executionContext, path, method, opts) { super.verifyNotDisposed(); const cancellationToken = FCancellationExecutionContext.of(executionContext).cancellationToken; let friendlyBody = null; let friendlyHeaders = {}; let limitToken = null; let limitWeight = 1; if (opts !== undefined) { const { headers, body } = opts; if (headers !== undefined) { friendlyHeaders = { ...headers }; } if (this._userAgent !== undefined && !("User-Agent" in friendlyHeaders)) { friendlyHeaders["User-Agent"] = this._userAgent; } if (body !== undefined) { friendlyBody = body; } if (opts.limitWeight !== undefined) { limitWeight = opts.limitWeight; } } try { if (this._limitHandle !== undefined) { const a = await this._limitHandle.instance.accrueTokenLazy(limitWeight, this._limitHandle.timeout, cancellationToken); limitToken = a; } else { friendlyHeaders["X-FLimit-Weight"] = limitWeight; } const url = new URL(path, this._baseUrl); const invokeArgs = { url, method, headers: friendlyHeaders }; if (friendlyBody !== null) { invokeArgs.body = friendlyBody; } const invokeResponse = await this._httpClient.invoke(executionContext, invokeArgs); const { statusCode, statusDescription, headers: responseHeaders, body } = invokeResponse; const response = { get statusCode() { return statusCode; }, get statusDescription() { return statusDescription; }, get headers() { return responseHeaders; }, get body() { return body; }, get bodyAsJson() { return JSON.parse(body.toString()); } }; if (limitToken !== null) { limitToken.commit(); } return response; } catch (e) { if (limitToken !== null) { if (e instanceof FHttpClient.CommunicationError) { // Token was not spent due server side did not do any jobs limitToken.rollback(); } else { limitToken.commit(); } } throw e; } } async onDispose() { if (this._limitHandle !== undefined) { if (this._limitHandle.isOwnInstance) { await this._limitHandle.instance.dispose(); } } } } //# sourceMappingURL=f_web_client.js.map