All files / kernel-rpc-methods/src types.ts

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111                                                                                                                                                                                                                             
import type { Infer, Struct } from '@metamask/superstruct';
import type { JsonRpcParams, Json } from '@metamask/utils';
 
// Client-side types
 
export type MethodSignature<
  Method extends string,
  Params extends JsonRpcParams,
  Result extends Json | Promise<Json>,
> = (method: Method, params: Params) => Result;
 
export type MethodSpec<
  Method extends string,
  Params extends JsonRpcParams,
  Result extends Json | Promise<Json> | void | Promise<void>,
> = Result extends void | Promise<void>
  ? { method: Method; params: Struct<Params>; result?: undefined }
  : {
      method: Method;
      params: Struct<Params>;
      result: Struct<UnwrapPromise<Result>>;
    };
 
// `any` can safely be used in constraints.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type SpecConstraint = MethodSpec<string, any, any>;
 
export type MethodSpecRecord<Methods extends SpecConstraint> = {
  [Key in Methods['method']]: Extract<Methods, { method: Key }>;
};
 
type SpecRecordConstraint = MethodSpecRecord<SpecConstraint>;
 
export type ExtractMethodSignature<Spec extends SpecConstraint> =
  Spec extends ((
    method: infer Method extends string,
    params: infer Params extends JsonRpcParams,
  ) => infer Result extends Json | Promise<Json>)
    ? MethodSignature<Method, Params, Result>
    : never;
 
export type ExtractMethodSpec<
  Specs extends SpecRecordConstraint,
  Key extends keyof Specs = keyof Specs,
> = Specs[Key];
 
export type ExtractMethod<Specs extends SpecRecordConstraint> =
  ExtractMethodSpec<Specs>['method'];
 
export type ExtractRequest<Specs extends SpecRecordConstraint> =
  // Safe to use `any` in constraints.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  Extract<ExtractMethodSpec<Specs>, { result: Struct<any> }>['method'];
 
export type ExtractNotification<Specs extends SpecRecordConstraint> = Extract<
  ExtractMethodSpec<Specs>,
  { result?: undefined }
>['method'];
 
export type ExtractParams<
  Method extends string,
  Specs extends SpecRecordConstraint,
> = Infer<ExtractMethodSpec<Specs, Method>['params']>;
 
export type ExtractResult<
  Method extends string,
  Specs extends SpecRecordConstraint,
> =
  // Safe to use `any` in constraints.
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  ExtractMethodSpec<Specs, Method> extends MethodSpec<any, any, infer Result>
    ? UnwrapPromise<Result>
    : never;
 
export type HandlerFunction<
  Params extends JsonRpcParams,
  Result extends Json | Promise<Json> | void | Promise<void>,
  Hooks extends Record<string, unknown>,
> = (hooks: Hooks, params: Params) => Result;
 
// Service-side types
 
export type Handler<
  Method extends string,
  Params extends JsonRpcParams,
  Result extends Json | Promise<Json> | void | Promise<void>,
  Hooks extends Record<string, unknown>,
> = MethodSpec<Method, Params, Result> & {
  hooks: { [Key in keyof Hooks]: true };
  implementation: HandlerFunction<Params, Result, Hooks>;
};
 
// `any` can safely be used in constraints.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type HandlerConstraint = Handler<string, any, any, any>;
 
export type HandlerRecord<Handlers extends HandlerConstraint> = {
  [Key in Handlers['method']]: Extract<Handlers, { method: Key }>;
};
 
// Utils
 
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
 
export type MethodRequest<Method extends SpecConstraint> = {
  id: string | number | null;
  jsonrpc: '2.0';
  method: Method['method'];
  params: Infer<Method['params']>;
};