@lodestar/api
Version:
A Typescript REST client for the Ethereum Consensus API
168 lines • 5.91 kB
JavaScript
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