All files / kernel-utils/src types.ts

100% Statements 27/27
100% Branches 8/8
100% Functions 12/12
100% Lines 19/19

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                                                      155x                   155x 17x   155x       15x   155x   17x   6x                                     155x           155x         155x 144x             155x           1942x 144x               155x   155x 48x 37x  
import type { Primitive } from '@endo/captp';
import type { PromiseKit } from '@endo/promise-kit';
import type { Infer, Struct } from '@metamask/superstruct';
import { array, empty, is, object, string, union } from '@metamask/superstruct';
import {
  isObject,
  UnsafeJsonStruct,
  JsonRpcRequestStruct,
  JsonRpcResponseStruct,
  JsonRpcNotificationStruct,
} from '@metamask/utils';
import type {
  JsonRpcNotification,
  JsonRpcRequest,
  JsonRpcResponse,
} from '@metamask/utils';
 
export type TypeGuard<Type> = (value: unknown) => value is Type;
 
export type ExtractGuardType<Guard, Bound = unknown> = Guard extends (
  value: unknown,
) => value is infer Type
  ? Type extends Bound
    ? Type
    : never
  : never;
 
const primitives = new Set([
  'string',
  'number',
  'bigint',
  'boolean',
  'symbol',
  'null',
  'undefined',
]);
 
export const isPrimitive = (value: unknown): value is Primitive =>
  value === null || primitives.has(typeof value);
 
export const isTypedArray = <ElementType>(
  value: unknown,
  isElement: TypeGuard<ElementType>,
): value is ElementType[] =>
  Array.isArray(value) && !value.some((ele) => !isElement(ele));
 
export const isTypedObject = <ValueType>(
  value: unknown,
  isValue: TypeGuard<ValueType>,
): value is { [Key in keyof object]: ValueType } =>
  isObject(value) && !Object.values(value).some((val) => !isValue(val));
 
export type PromiseCallbacks<Resolve = unknown> = Omit<
  PromiseKit<Resolve>,
  'promise'
>;
 
/**
 * Utility type that wraps all method return types in Promise.
 * Methods already returning Promise<T> remain Promise<T>.
 */
export type Promisified<T> = {
  [K in keyof T]: T[K] extends (...args: infer A) => Promise<infer R>
    ? (...args: A) => Promise<R>
    : T[K] extends (...args: infer A) => infer R
      ? (...args: A) => Promise<R>
      : T[K];
};
 
export const EmptyJsonArray = empty(array(UnsafeJsonStruct));
 
export type EmptyJsonArray = Infer<typeof EmptyJsonArray>;
 
export type JsonRpcCall = JsonRpcRequest | JsonRpcNotification;
 
export const JsonRpcCallStruct: Struct<JsonRpcCall> = union([
  JsonRpcRequestStruct,
  JsonRpcNotificationStruct,
]);
 
export const isJsonRpcCall = (value: unknown): value is JsonRpcCall =>
  is(value, JsonRpcCallStruct);
 
export type JsonRpcMessage =
  | JsonRpcNotification
  | JsonRpcRequest
  | JsonRpcResponse;
 
export const JsonRpcMessageStruct: Struct<JsonRpcMessage> = union([
  JsonRpcNotificationStruct,
  JsonRpcRequestStruct,
  JsonRpcResponseStruct,
]);
 
export const isJsonRpcMessage = (value: unknown): value is JsonRpcMessage =>
  is(value, JsonRpcMessageStruct);
 
/**
 * Check whether a value has the shape of Endo CapData (`{ body: string, slots: string[] }`).
 *
 * @param value - The value to check.
 * @returns `true` when `value` looks like CapData.
 */
export const CapDataStruct = object({ body: string(), slots: array(string()) });
 
export const isCapData = (
  value: unknown,
): value is { body: string; slots: string[] } => is(value, CapDataStruct);