{"version":3,"file":"assertions.cjs","names":[],"sources":["../../src/utils/error.ts","../../src/utils/assertions.ts"],"sourcesContent":["/** Coerce an unknown caught value to an Error instance. */\nexport function toError(error: unknown): Error {\n  if (error instanceof Error) {\n    return error;\n  }\n  if (typeof error === \"object\" && error !== null && \"message\" in error) {\n    return new Error(String(error.message));\n  }\n  return new Error(String(error));\n}\n\n/**\n * Returns true if the error is a contract call revert (as opposed to a network/transport error).\n * Detects viem's ContractFunctionExecutionError / ContractFunctionRevertedError\n * and ethers' CALL_EXCEPTION.\n */\nexport function isContractCallError(error: unknown): boolean {\n  if (!(error instanceof Error)) {\n    return false;\n  }\n  // viem: ContractFunctionExecutionError, ContractFunctionRevertedError\n  if (\n    error.name === \"ContractFunctionExecutionError\" ||\n    error.name === \"ContractFunctionRevertedError\"\n  ) {\n    return true;\n  }\n  // ethers: error.code === \"CALL_EXCEPTION\"\n  if (\"code\" in error && error.code === \"CALL_EXCEPTION\") {\n    return true;\n  }\n  // Fallback: common revert message patterns from various providers\n  const msg = error.message.toLowerCase();\n  return msg.includes(\"execution reverted\") || msg.includes(\"call revert exception\");\n}\n\n/** JSON-RPC error code providers use for rate limiting (\"limit exceeded\"). */\nconst JSON_RPC_LIMIT_EXCEEDED = -32005;\n\n/** Properties that may nest a lower-level cause across viem / ethers / fetch. */\nconst NESTED_ERROR_KEYS = [\"cause\", \"error\", \"info\"] as const;\n\n/**\n * Walk an error and its nested causes (`cause` / `error` / `info`, as used by\n * viem, ethers, and fetch wrappers), applying `predicate` to each object node.\n * Returns the first node for which `predicate` returns true, or `undefined`.\n * Depth-bounded to avoid pathological / cyclic structures.\n */\nfunction findInErrorChain(\n  error: unknown,\n  predicate: (node: Record<string, unknown>) => boolean,\n  depth = 6,\n): Record<string, unknown> | undefined {\n  if (depth < 0 || error === null || error === undefined || typeof error !== \"object\") {\n    return undefined;\n  }\n  const node = error as Record<string, unknown>;\n  if (predicate(node)) {\n    return node;\n  }\n  for (const key of NESTED_ERROR_KEYS) {\n    const next = node[key];\n    if (next !== undefined && next !== null && typeof next === \"object\") {\n      const found = findInErrorChain(next, predicate, depth - 1);\n      if (found) {\n        return found;\n      }\n    }\n  }\n  return undefined;\n}\n\n// ============================================================================\n// Cross-thread serialization\n// ============================================================================\n\n/**\n * A plain, structured-clone-safe snapshot of an error and its cause chain.\n *\n * The worker boundary (`postMessage`) strips prototypes, `code`/`status`, and —\n * critically — the `cause` chain, leaving only the message. Decryption errors\n * are classified on the **main thread** ({@link wrapDecryptError}), so the worker\n * only needs to faithfully hand the error across the boundary, not understand it.\n * `serializeError` is that mechanical, taxonomy-agnostic envelope: it copies the\n * scalar signal fields the classifier keys on and flattens the nested cause chain\n * into a single `cause` link. {@link deserializeError} rebuilds an `Error` whose\n * `.cause` chain mirrors the original, so the existing chain-walking detectors\n * work on it unchanged.\n */\nexport interface SerializedError {\n  name: string;\n  message: string;\n  /** e.g. JSON-RPC -32005, \"RELAYER_FETCH_ERROR\", ethers \"CALL_EXCEPTION\". */\n  code?: string | number;\n  /** viem-style HTTP status. */\n  status?: number;\n  /** relayer / node-fetch-style HTTP status. */\n  statusCode?: number;\n  /** Server-driven retry delay in **seconds** (numeric prop or parsed `Retry-After`). */\n  retryAfter?: number;\n  /**\n   * ethers surfaces an HTTP status only as a string on `info.responseStatus`\n   * (e.g. `\"429 Too Many Requests\"`), not as a numeric `status`. It lives on a\n   * nested `info` object the flattening would otherwise skip, so it is lifted\n   * onto the envelope and rebuilt onto `error.info.responseStatus`, letting the\n   * ethers rate-limit detector classify a worker-origin 429 exactly as it would\n   * the same error on the main thread.\n   */\n  responseStatus?: string;\n  cause?: SerializedError;\n}\n\n/** Scalar signal fields carried verbatim across the boundary, in both directions. */\nconst SERIALIZED_SCALAR_KEYS = [\"code\", \"status\", \"statusCode\", \"retryAfter\"] as const;\n\n/**\n * ethers reports its HTTP status only as a string on `info.responseStatus`\n * (e.g. `\"429 Too Many Requests\"`). Read it directly off the node — not via the\n * cause-chain flattening, which descends a single branch — so it survives even\n * when the error also carries an `error` link that would be walked first.\n */\nfunction responseStatusFromNode(node: Record<string, unknown>): string | undefined {\n  const info = node.info;\n  if (info !== null && typeof info === \"object\") {\n    const responseStatus = (info as Record<string, unknown>).responseStatus;\n    if (typeof responseStatus === \"string\") {\n      return responseStatus;\n    }\n  }\n  return undefined;\n}\n\n/**\n * Copy the scalar signal fields the classifier keys on from a raw error node\n * onto the envelope, only where not already set — so a shallower node keeps\n * priority. Also lifts ethers' string `info.responseStatus` and the relayer's\n * `Retry-After` header (both destroyed by structured clone: the header lives on\n * a non-cloneable `Headers`, the status on a nested `info` the flattening skips).\n */\nfunction captureNodeSignals(node: Record<string, unknown>, into: SerializedError): void {\n  if (into.code === undefined && (typeof node.code === \"string\" || typeof node.code === \"number\")) {\n    into.code = node.code;\n  }\n  if (into.status === undefined && typeof node.status === \"number\") {\n    into.status = node.status;\n  }\n  if (into.statusCode === undefined && typeof node.statusCode === \"number\") {\n    into.statusCode = node.statusCode;\n  }\n  if (into.responseStatus === undefined) {\n    const responseStatus = responseStatusFromNode(node);\n    if (responseStatus !== undefined) {\n      into.responseStatus = responseStatus;\n    }\n  }\n  if (into.retryAfter === undefined) {\n    if (typeof node.retryAfter === \"number\") {\n      into.retryAfter = node.retryAfter;\n    } else {\n      const fromHeader = retryAfterFromHeader(node);\n      if (fromHeader !== undefined) {\n        into.retryAfter = fromHeader;\n      }\n    }\n  }\n}\n\n/** Lift any still-missing scalar signal from an already-serialized child up. */\nfunction hoistMissingSignals(from: SerializedError, into: SerializedError): void {\n  if (into.code === undefined && from.code !== undefined) {\n    into.code = from.code;\n  }\n  if (into.status === undefined && from.status !== undefined) {\n    into.status = from.status;\n  }\n  if (into.statusCode === undefined && from.statusCode !== undefined) {\n    into.statusCode = from.statusCode;\n  }\n  if (into.responseStatus === undefined && from.responseStatus !== undefined) {\n    into.responseStatus = from.responseStatus;\n  }\n  if (into.retryAfter === undefined && from.retryAfter !== undefined) {\n    into.retryAfter = from.retryAfter;\n  }\n}\n\n/**\n * Flatten an error (and its `cause` / `error` / `info` chain) into a\n * structured-clone-safe {@link SerializedError}. Depth-bounded to mirror\n * {@link findInErrorChain} and guard against cyclic structures.\n */\nexport function serializeError(error: unknown, depth = 6): SerializedError {\n  const coerced = toError(error);\n  const node =\n    typeof error === \"object\" && error !== null\n      ? (error as Record<string, unknown>)\n      : (coerced as unknown as Record<string, unknown>);\n\n  const serialized: SerializedError = { name: coerced.name, message: coerced.message };\n  captureNodeSignals(node, serialized);\n\n  if (depth > 0) {\n    // Walk *every* nested link (`cause` / `error` / `info`), not just the first\n    // present one: an error commonly carries several (ethers puts the underlying\n    // fault on `error` and the HTTP status on `info`), and the signal-bearing\n    // branch is not always the first. Keep the first as the representative\n    // `.cause` for message/chain fidelity, and lift any still-missing scalar\n    // signal off the others so none is dropped.\n    for (const key of NESTED_ERROR_KEYS) {\n      const next = node[key];\n      if (next !== undefined && next !== null && typeof next === \"object\") {\n        const child = serializeError(next, depth - 1);\n        if (serialized.cause === undefined) {\n          serialized.cause = child;\n        }\n        hoistMissingSignals(child, serialized);\n      }\n    }\n  }\n\n  return serialized;\n}\n\n/**\n * Rebuild a real {@link Error} from a {@link SerializedError}, re-attaching the\n * scalar signal fields and reconstructing the `.cause` chain so chain-walking\n * detectors ({@link findInErrorChain}, {@link extractHttpStatus},\n * {@link isRpcRateLimitError}) operate on it exactly as on the original.\n */\nexport function deserializeError(serialized: SerializedError): Error {\n  const error = new Error(serialized.message) as Error & Record<string, unknown>;\n  if (serialized.name) {\n    error.name = serialized.name;\n  }\n  for (const key of SERIALIZED_SCALAR_KEYS) {\n    const value = serialized[key];\n    if (value !== undefined) {\n      error[key] = value;\n    }\n  }\n  // Rebuild ethers' `info.responseStatus` on the same node as its `code`, so the\n  // ethers rate-limit detector (`code: \"SERVER_ERROR\"` + `info.responseStatus`)\n  // matches the round-tripped error exactly as it would the original.\n  if (serialized.responseStatus !== undefined) {\n    error.info = { responseStatus: serialized.responseStatus };\n  }\n  if (serialized.cause) {\n    error.cause = deserializeError(serialized.cause);\n  }\n  return error;\n}\n\n// ============================================================================\n// Classification detectors (main-thread)\n// ============================================================================\n\n/**\n * Structured (unambiguous) consumer rate-limit signal across the RPC providers\n * the SDK reads through:\n * - JSON-RPC `-32005` (\"limit exceeded\");\n * - viem-style numeric `status: 429`, and viem's own `shouldRetry` shape where\n *   the JSON-RPC error `code` is `429`;\n * - ethers' 429, which surfaces as `code: \"SERVER_ERROR\"` with the status only\n *   in `info.responseStatus` (a string like `\"429 Too Many Requests\"`) and no\n *   numeric top-level status — the leading code is parsed out of it.\n *\n * Deliberately NOT `statusCode: 429` — that is the relayer / node-fetch HTTP\n * shape, which stays {@link RelayerRequestFailedError} (SDK-236), so a relayer\n * 429 is never mistaken for a consumer-RPC throttle.\n */\nfunction nodeHasStructuredRateLimit(node: Record<string, unknown>): boolean {\n  if (node.code === JSON_RPC_LIMIT_EXCEEDED || node.status === 429 || node.code === 429) {\n    return true;\n  }\n  // ethers: `code: \"SERVER_ERROR\"`, status lives in `info.responseStatus`.\n  if (node.code === \"SERVER_ERROR\" && typeof node.info === \"object\" && node.info !== null) {\n    const responseStatus = (node.info as Record<string, unknown>).responseStatus;\n    if (typeof responseStatus === \"string\" && /^\\s*429\\b/.test(responseStatus)) {\n      return true;\n    }\n  }\n  return false;\n}\n\nfunction nodeIsRpcRateLimit(node: Record<string, unknown>): boolean {\n  if (nodeHasStructuredRateLimit(node)) {\n    return true;\n  }\n  // Message fallback for providers without a structured code. Deliberately\n  // narrow (specific throttling phrases, no bare \"429\") to avoid false positives\n  // that would turn a terminal error into a retryable one.\n  if (typeof node.message === \"string\") {\n    const msg = node.message.toLowerCase();\n    return (\n      msg.includes(\"too many requests\") || msg.includes(\"rate limit\") || msg.includes(\"rate-limit\")\n    );\n  }\n  return false;\n}\n\n/**\n * The relayer SDK tags its HTTP errors with `code: \"RELAYER_FETCH_ERROR\"`. These\n * stay the relayer's domain ({@link RelayerRequestFailedError} / SDK-236), never\n * {@link RpcRateLimitError}, even on a 429.\n */\nfunction isRelayerFetchError(error: unknown): boolean {\n  return findInErrorChain(error, (node) => node.code === \"RELAYER_FETCH_ERROR\") !== undefined;\n}\n\n/**\n * True if the error is the consumer's RPC provider throttling an on-chain read\n * (HTTP 429 / JSON-RPC -32005). Relayer-originated 429s are excluded.\n */\nexport function isRpcRateLimitError(error: unknown): boolean {\n  if (isRelayerFetchError(error)) {\n    return false;\n  }\n  return findInErrorChain(error, nodeIsRpcRateLimit) !== undefined;\n}\n\n/**\n * Like {@link isRpcRateLimitError} but only matches an unambiguous **structured**\n * signal (`-32005` or a viem `status: 429`), ignoring message text. The classifier\n * promotes this ahead of any HTTP status, while a message-only throttle is only\n * trusted when no status is present — so a relayer HTTP error whose body happens\n * to say \"rate limit\" still maps to {@link RelayerRequestFailedError}.\n */\nexport function hasStructuredRpcRateLimitSignal(error: unknown): boolean {\n  if (isRelayerFetchError(error)) {\n    return false;\n  }\n  return findInErrorChain(error, nodeHasStructuredRateLimit) !== undefined;\n}\n\n/**\n * Transport-error signatures of the consumer's own RPC client (viem / ethers).\n * The worker's on-chain reads (the ACL `persistAllowed` pre-check) go through\n * that client, which already retries transport faults internally — so a failure\n * carrying one of these shapes must NOT be retried again by the SDK on top.\n */\nfunction nodeHasConsumerRpcSignature(node: Record<string, unknown>): boolean {\n  // ethers transient transport codes.\n  const code = node.code;\n  if (code === \"NETWORK_ERROR\" || code === \"SERVER_ERROR\" || code === \"TIMEOUT\") {\n    return true;\n  }\n  // viem transport error classes (the `name` survives the worker boundary).\n  const name = node.name;\n  return (\n    name === \"HttpRequestError\" ||\n    name === \"RpcRequestError\" ||\n    name === \"TimeoutError\" ||\n    name === \"WebSocketRequestError\"\n  );\n}\n\n/**\n * True when a failure originates from the **consumer's RPC provider** (viem /\n * ethers) rather than the relayer. Keeps the SDK's relayer retry from\n * double-retrying transport faults the integrator's client already retried.\n * A relayer HTTP error (`RELAYER_FETCH_ERROR`) is never consumer-RPC.\n */\nexport function isConsumerRpcError(error: unknown): boolean {\n  if (isRelayerFetchError(error)) {\n    return false;\n  }\n  if (hasStructuredRpcRateLimitSignal(error)) {\n    return true;\n  }\n  return findInErrorChain(error, nodeHasConsumerRpcSignature) !== undefined;\n}\n\n/**\n * True only for transient faults attributable to the **relayer transport** — the\n * one network actor the SDK owns retries for, since viem/ethers don't model the\n * relayer. This is the single gate for {@link withRetry}.\n *\n * Two-tier retry model:\n * - **Relayer transport** (here): a relayer HTTP 502/503/504 — tagged\n *   `RELAYER_FETCH_ERROR` with a gateway status — or a relayer-boundary network\n *   failure (the relayer SDK uses bare `fetch`, so a transport error with no\n *   viem/ethers signature is the relayer connection itself). Retried.\n * - **Consumer RPC** ({@link isConsumerRpcError}): deferred to viem/ethers, never\n *   retried here. Timeouts are owned by viem/ethers and the worker-level\n *   operation timeout (SDK-237), so they are not auto-retried at this layer.\n *\n * Relayer back-pressure (HTTP 429) is deliberately excluded: it is surfaced to\n * the caller as a retryable {@link RelayerRequestFailedError} with `retryAfter`,\n * not silently retried.\n */\nexport function isRetryableRelayerError(error: unknown): boolean {\n  if (!(error instanceof Error)) {\n    return false;\n  }\n  if (isConsumerRpcError(error)) {\n    return false;\n  }\n  // Relayer HTTP gateway transients (502/503/504), tagged by the relayer SDK.\n  const relayerGatewayError = findInErrorChain(\n    error,\n    (n) =>\n      n.code === \"RELAYER_FETCH_ERROR\" &&\n      (n.status === 502 || n.status === 503 || n.status === 504),\n  );\n  if (relayerGatewayError) {\n    return true;\n  }\n  // Relayer-boundary transport failure (no consumer-RPC signature above).\n  const msg = error.message.toLowerCase();\n  return (\n    msg.includes(\"econnreset\") ||\n    msg.includes(\"econnrefused\") ||\n    msg.includes(\"socket hang up\") ||\n    msg.includes(\"fetch failed\") ||\n    msg.includes(\"network\")\n  );\n}\n\n/**\n * The relayer SDK's ACL gate (`validateAclPermissions`) throws a message-only\n * Error when the actor isn't allowed: `User address <a> is not authorized to\n * user decrypt handle <h>!`. Matching it here, once, against the pinned\n * `@zama-fhe/relayer-sdk`, is what lets {@link wrapDecryptError} surface a typed\n * NotEntitledError (the \"dapp contract … is not authorized\" variant is a dapp\n * misconfig and is intentionally left to DecryptionFailedError).\n *\n * This is a deliberate bridge, not a destination: `@zama-fhe/relayer-sdk` ships\n * a typed `ACLUserDecryptionError`, but its active `userDecrypt` path still\n * throws a plain Error. TODO(SDK-239 follow-up): once the relayer surfaces the\n * typed/coded ACL error from that path, key off the code instead of the message\n * and drop this matcher. The `error.test.ts` guard reads the installed relayer\n * source and fails loudly if the message drifts before then.\n */\nexport function isNotEntitledMessage(message: string): boolean {\n  const m = message.toLowerCase();\n  return m.includes(\"user address\") && m.includes(\"is not authorized to user decrypt\");\n}\n\n/** Parse the on-chain handle out of the relayer's not-entitled message. */\nexport function parseHandleFromMessage(message: string): string | undefined {\n  return /handle (0x[0-9a-fA-F]{64})/.exec(message)?.[1];\n}\n\n/**\n * Parse an HTTP `Retry-After` header value into **seconds** (the SDK's duration\n * unit and the header's own unit), or `undefined` when absent/unparseable. Per\n * RFC 9110 the value is either a non-negative number of seconds (`\"120\"`) or an\n * HTTP-date; a past date floors to `0`.\n */\nexport function parseRetryAfterHeader(value: string | null | undefined): number | undefined {\n  if (value === null || value === undefined) {\n    return undefined;\n  }\n  const trimmed = value.trim();\n  if (trimmed === \"\") {\n    return undefined;\n  }\n  // delta-seconds: a non-negative integer (already the unit we want).\n  if (/^\\d+$/.test(trimmed)) {\n    return Number(trimmed);\n  }\n  // HTTP-date — an IMF-fixdate always carries alphabetic day/month names, so\n  // require a letter before deferring to the lenient Date.parse.\n  if (/[a-zA-Z]/.test(trimmed)) {\n    const dateMs = Date.parse(trimmed);\n    if (!Number.isNaN(dateMs)) {\n      return Math.max(0, Math.round((dateMs - Date.now()) / 1000));\n    }\n  }\n  return undefined;\n}\n\n/** Read a `Retry-After` header (→ seconds) off a `Headers`-like object, if present. */\nfunction readRetryAfterHeader(headers: unknown): number | undefined {\n  if (headers === null || typeof headers !== \"object\") {\n    return undefined;\n  }\n  const get = (headers as { get?: unknown }).get;\n  if (typeof get !== \"function\") {\n    return undefined;\n  }\n  return parseRetryAfterHeader(\n    (get as (name: string) => string | null).call(headers, \"Retry-After\"),\n  );\n}\n\n/**\n * A node's **relayer** `Retry-After` header (seconds), read from a wrapped fetch\n * `Response` (the relayer SDK's `cause.response.headers`). The SDK owns the\n * relayer fetch, so parsing the header there is legitimate.\n *\n * The viem/chain side (`HttpRequestError.headers`) is deliberately **not** read:\n * for consumer RPC the integrator's viem/ethers transport already honors\n * `Retry-After` in its own retry loop (and retries) before the error ever\n * surfaces, so re-reading it here would re-implement a transport concern.\n * Chain-RPC backoff is configured on the consumer's transport (`chain.network`).\n */\nfunction retryAfterFromHeader(node: Record<string, unknown>): number | undefined {\n  const response = node.response;\n  if (response !== null && typeof response === \"object\") {\n    return readRetryAfterHeader((response as Record<string, unknown>).headers);\n  }\n  return undefined;\n}\n\n/**\n * A single node's server-driven retry delay (seconds): a numeric `retryAfter`\n * (a non-positive synthetic value is ignored), else a `Retry-After` header.\n */\nfunction retryAfterFromNode(node: Record<string, unknown>): number | undefined {\n  if (\n    typeof node.retryAfter === \"number\" &&\n    Number.isFinite(node.retryAfter) &&\n    node.retryAfter > 0\n  ) {\n    return node.retryAfter;\n  }\n  return retryAfterFromHeader(node);\n}\n\n/**\n * Best-effort extraction of a server-driven retry delay, in **seconds**, from\n * anywhere in an error's cause chain. Reads a numeric `retryAfter` property and\n * the **relayer's** `Retry-After` header (`cause.response.headers`). The\n * consumer-RPC/chain side is intentionally not read — viem/ethers own that\n * backoff (see {@link retryAfterFromHeader}). `undefined` when absent.\n */\nexport function extractRetryAfter(error: unknown): number | undefined {\n  const node = findInErrorChain(error, (n) => retryAfterFromNode(n) !== undefined);\n  return node ? retryAfterFromNode(node) : undefined;\n}\n\n/**\n * Extract an HTTP status code from an error or anywhere in its cause chain.\n * Relayer SDK errors may carry a `status` or `statusCode` property; walking the\n * full chain (rather than just depth-1) keeps this in step with the other\n * chain-walking detectors and avoids a depth asymmetry between them.\n */\nexport function extractHttpStatus(error: unknown): number | undefined {\n  const node = findInErrorChain(\n    error,\n    (n) => typeof n.statusCode === \"number\" || typeof n.status === \"number\",\n  );\n  if (!node) {\n    return undefined;\n  }\n  return (typeof node.statusCode === \"number\" ? node.statusCode : node.status) as number;\n}\n","export function assertNonNullable<T>(value: T, context: string): asserts value is NonNullable<T> {\n  if (value === null || value === undefined) {\n    throw new TypeError(`${context} must not be null or undefined`);\n  }\n}\n\nexport function assertObject(\n  value: unknown,\n  context: string,\n): asserts value is Record<string, unknown> {\n  if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n    throw new TypeError(`${context} must be an object, got ${typeof value}`);\n  }\n}\n\nexport function assertString(value: unknown, context: string): asserts value is string {\n  if (typeof value !== \"string\") {\n    throw new TypeError(`${context} must be a string, got ${typeof value}`);\n  }\n}\n\nexport function assertArray(value: unknown, context: string): asserts value is unknown[] {\n  if (!Array.isArray(value)) {\n    throw new TypeError(`${context} must be an array, got ${typeof value}`);\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function assertFunction(value: unknown, context: string): asserts value is Function {\n  if (typeof value !== \"function\") {\n    throw new TypeError(`${context} must be a function, got ${typeof value}`);\n  }\n}\n\nexport function assertBigint(value: unknown, context: string): asserts value is bigint {\n  if (typeof value !== \"bigint\") {\n    throw new TypeError(`${context} must be a bigint, got ${typeof value}`);\n  }\n}\n\n/** Assert that `obj[key]` is a string. Narrows `obj` to include `{ [key]: string }`. */\nexport function assertStringProp<\n  K extends string,\n  O extends Record<string, unknown> = Record<string, unknown>,\n>(obj: O, key: K, context: string): asserts obj is O & Record<K, string> {\n  assertString(obj[key], context);\n}\n\n/** Assert that `obj[key]` is a function. Narrows `obj` to include `{ [key]: F }`. */\nexport function assertFunctionProp<\n  K extends string,\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n  F extends Function,\n  O extends Record<string, unknown> = Record<string, unknown>,\n>(obj: O, key: K, context: string): asserts obj is O & Record<K, F> {\n  assertFunction(obj[key], context);\n}\n\nexport function assertCondition(condition: boolean, message: string): asserts condition {\n  if (!condition) {\n    throw new TypeError(message);\n  }\n}\n"],"mappings":"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"}