@lodestar/api
Version:
A Typescript REST client for the Ethereum Consensus API
129 lines • 5.42 kB
TypeScript
import { ExtraRequestInit } from "./client/request.js";
import { EmptyMeta } from "./codecs.js";
import { HeadersExtra } from "./headers.js";
import { SchemaDefinition } from "./schema.js";
import { WireFormat } from "./wireFormat.js";
export type HasOnlyOptionalProps<T> = {
[K in keyof T]-?: object extends Pick<T, K> ? never : K;
} extends {
[K2 in keyof T]: never;
} ? true : false;
export type PathParams = Record<string, string | number>;
export type QueryParams = Record<string, string | number | boolean | (string | number)[]>;
export type HeaderParams = Record<string, string>;
export type RequestData<P extends PathParams = PathParams, Q extends QueryParams = QueryParams, H extends HeaderParams = HeaderParams> = {
params?: P;
query?: Q;
headers?: H;
};
export type JsonRequestData<B = unknown, P extends PathParams = PathParams, Q extends QueryParams = QueryParams, H extends HeaderParams = HeaderParams> = RequestData<P, Q, H> & {
body?: B;
};
export type SszRequestData<P extends JsonRequestData> = Omit<P, "body"> & ("body" extends keyof P ? (P["body"] extends void ? {
body?: never;
} : {
body: Uint8Array;
}) : {
body?: never;
});
export type HttpMethod = "GET" | "POST" | "DELETE";
/**
* This type describes the general shape of a route
*
* This includes both http and application-level shape
* - The http method
* - Used to more strictly enforce the shape of the request
* - The application-level parameters
* - this enforces the shape of the input data passed by the client and to the route handler
* - The http request
* - this enforces the shape of the querystring, url params, request body
* - The application-level return data
* - this enforces the shape of the output data passed back to the client and returned by the route handler
* - The application-level return metadata
* - this enforces the shape of the returned metadata, used informationally and to help decode the return data
*/
export type Endpoint<Method extends HttpMethod = HttpMethod, ArgsType = unknown, RequestType extends Method extends "GET" ? RequestData : JsonRequestData = JsonRequestData, ReturnType = unknown, Meta = unknown> = {
method: Method;
/** The parameters the client passes / server app code ingests */
args: ArgsType;
/** The parameters in the http request */
request: RequestType;
/** The return data */
return: ReturnType;
/** The return metadata */
meta: Meta;
};
/** Encode / decode requests to & from function params, as well as schema definitions */
export type RequestWithoutBodyCodec<E extends Endpoint> = {
writeReq: (p: E["args"]) => E["request"];
parseReq: (r: E["request"]) => E["args"];
schema: SchemaDefinition<E["request"]>;
};
export type JsonRequestMethods<E extends Endpoint> = {
writeReqJson: (p: E["args"]) => E["request"];
parseReqJson: (r: E["request"]) => E["args"];
};
export type SszRequestMethods<E extends Endpoint> = {
writeReqSsz: (p: E["args"]) => SszRequestData<E["request"]>;
parseReqSsz: (r: SszRequestData<E["request"]>) => E["args"];
};
export type RequestWithBodyCodec<E extends Endpoint> = JsonRequestMethods<E> & SszRequestMethods<E> & {
schema: SchemaDefinition<E["request"]>;
/** Support ssz-only or json-only requests */
onlySupport?: WireFormat;
};
/**
* Handles translation between `Endpoint["args"]` and `Endpoint["request"]`
*/
export type RequestCodec<E extends Endpoint> = E["method"] extends "GET" ? RequestWithoutBodyCodec<E> : "body" extends keyof E["request"] ? RequestWithBodyCodec<E> : RequestWithoutBodyCodec<E>;
export declare function isRequestWithoutBody<E extends Endpoint>(definition: RouteDefinition<E>): definition is RouteDefinition<E> & {
req: RequestWithoutBodyCodec<E>;
};
export type ResponseDataCodec<T, M> = {
toJson: (data: T, meta: M) => unknown;
fromJson: (data: unknown, meta: M) => T;
serialize: (data: T, meta: M) => Uint8Array;
deserialize: (data: Uint8Array, meta: M) => T;
};
export type ResponseMetadataCodec<T> = {
toJson: (val: T) => unknown;
fromJson: (val: unknown) => T;
toHeadersObject: (val: T) => Record<string, string>;
fromHeaders: (headers: HeadersExtra) => T;
};
export type ResponseCodec<E extends Endpoint> = {
data: ResponseDataCodec<E["return"], E["meta"]>;
meta: ResponseMetadataCodec<E["meta"]>;
/** Occasionally, json responses require an extra transformation to separate the data from metadata */
transform?: {
toResponse: (data: unknown, meta: unknown) => unknown;
fromResponse: (resp: unknown) => {
data: E["return"];
} & (E["meta"] extends EmptyMeta ? {
meta?: never;
} : {
meta: E["meta"];
});
};
/** Support ssz-only or json-only responses */
onlySupport?: WireFormat;
/** Indicator used to handle empty responses */
isEmpty?: true;
};
/**
* Top-level definition of a route used by both the client and server
* - url and method
* - request and response codec
* - request json schema
*/
export type RouteDefinition<E extends Endpoint> = {
url: string;
method: E["method"];
req: RequestCodec<E>;
resp: ResponseCodec<E>;
init?: ExtraRequestInit;
};
export type RouteDefinitions<Es extends Record<string, Endpoint>> = {
[K in keyof Es]: RouteDefinition<Es[K]>;
};
//# sourceMappingURL=types.d.ts.map