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                                                      147x                   147x 17x   147x       15x   147x   17x   6x                                     147x           147x         147x 136x             147x           1933x 136x               147x   147x 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);