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                                                      148x                   148x 17x   148x       15x   148x   17x   6x                                     148x           148x         148x 137x             148x           1942x 137x               148x   148x 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);