UNPKG

@lodestar/api

Version:

A Typescript REST client for the Ethereum Consensus API

168 lines 5.91 kB
import { HeadersExtra, HttpHeader, parseContentTypeHeader } from "../headers.js"; import { HttpStatusCode } from "../httpStatusCode.js"; import { WireFormat, getWireFormat } from "../wireFormat.js"; import { ApiError } from "./error.js"; export class ApiResponse extends Response { constructor(definition, body, init) { super(body, init); this.definition = definition; } wireFormat() { if (this._wireFormat === undefined) { if (this.definition.resp.isEmpty) { this._wireFormat = null; return this._wireFormat; } const contentType = this.headers.get(HttpHeader.ContentType); if (contentType === null) { if (this.status === HttpStatusCode.NO_CONTENT) { this._wireFormat = null; return this._wireFormat; } throw Error("Content-Type header is required in response"); } const mediaType = parseContentTypeHeader(contentType); if (mediaType === null) { throw Error(`Unsupported response media type: ${contentType.split(";", 1)[0]}`); } const wireFormat = getWireFormat(mediaType); const { onlySupport } = this.definition.resp; if (onlySupport !== undefined && wireFormat !== onlySupport) { throw Error(`Method only supports ${onlySupport.toUpperCase()} responses`); } this._wireFormat = wireFormat; } return this._wireFormat; } async rawBody() { this.assertOk(); if (!this._rawBody) { switch (this.wireFormat()) { case WireFormat.json: this._rawBody = { type: WireFormat.json, value: await super.json(), }; break; case WireFormat.ssz: this._rawBody = { type: WireFormat.ssz, value: new Uint8Array(await this.arrayBuffer()), }; break; default: this._rawBody = {}; } } return this._rawBody; } meta() { this.assertOk(); if (!this._meta) { switch (this.wireFormat()) { case WireFormat.json: { const rawBody = this.resolvedRawBody(); const metaJson = this.definition.resp.transform ? this.definition.resp.transform.fromResponse(rawBody.value).meta : rawBody.value; this._meta = this.definition.resp.meta.fromJson(metaJson); break; } case WireFormat.ssz: this._meta = this.definition.resp.meta.fromHeaders(new HeadersExtra(this.headers)); break; } } return this._meta; } value() { this.assertOk(); if (!this._value) { const rawBody = this.resolvedRawBody(); const meta = this.meta(); switch (rawBody.type) { case WireFormat.json: { const dataJson = this.definition.resp.transform ? this.definition.resp.transform.fromResponse(rawBody.value).data : rawBody.value?.data; this._value = this.definition.resp.data.fromJson(dataJson, meta); break; } case WireFormat.ssz: this._value = this.definition.resp.data.deserialize(rawBody.value, meta); break; } } return this._value; } ssz() { this.assertOk(); const rawBody = this.resolvedRawBody(); switch (rawBody.type) { case WireFormat.json: return this.definition.resp.data.serialize(this.value(), this.meta()); case WireFormat.ssz: return rawBody.value; default: return new Uint8Array(); } } json() { this.assertOk(); const rawBody = this.resolvedRawBody(); switch (rawBody.type) { case WireFormat.json: return rawBody.value; case WireFormat.ssz: return this.definition.resp.data.toJson(this.value(), this.meta()); default: return {}; } } assertOk() { if (!this.ok) { throw this.error(); } } error() { if (this.ok) { return null; } return new ApiError(this.getErrorMessage(), this.status, this.definition.operationId); } async errorBody() { if (this._errorBody === undefined) { this._errorBody = await this.text(); } return this._errorBody; } resolvedRawBody() { if (!this._rawBody) { throw Error("rawBody() must be called first"); } return this._rawBody; } resolvedErrorBody() { if (this._errorBody === undefined) { throw Error("errorBody() must be called first"); } return this._errorBody; } getErrorMessage() { const errBody = this.resolvedErrorBody(); try { const errJson = JSON.parse(errBody); if (errJson.message) { if (errJson.failures) { return `${errJson.message}\n` + errJson.failures.map((e) => e.message).join("\n"); } return errJson.message; } return errBody; } catch (_e) { return errBody || this.statusText; } } } //# sourceMappingURL=response.js.map