{"version":3,"file":"assert.mjs","sourceRoot":"","sources":["../src/assert.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,iBAAiB,EAAE,8BAA8B;AAEpE,OAAO,EAAE,eAAe,EAAE,qBAAiB;AAM3C;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,EAA6B;IAE7B,0BAA0B;IAC1B,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC;AACvE,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,oCAAoC,CAAC,KAAc;IAC1D,4BAA4B;IAC5B,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,gEAAgE;AAChE,SAAS,QAAQ,CAAC,YAAuC,EAAE,OAAe;IACxE,IAAI,eAAe,CAAC,YAAY,CAAC,EAAE;QACjC,OAAO,IAAI,YAAY,CAAC;YACtB,OAAO;SACR,CAAC,CAAC;KACJ;IACD,OAAO,YAAY,CAAC;QAClB,OAAO;KACR,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGvC,YAAY,OAA4B;QACtC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAHhB,SAAI,GAAG,eAAe,CAAC;IAIhC,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CACpB,KAAU,EACV,UAA0B,mBAAmB;AAC7C,gEAAgE;AAChE,eAA0C,cAAc;IAExD,IAAI,CAAC,KAAK,EAAE;QACV,IAAI,OAAO,YAAY,KAAK,EAAE;YAC5B,MAAM,OAAO,CAAC;SACf;QAED,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;KACvC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAc,EACd,MAA4B,EAC5B,WAAW,GAAG,kBAAkB;AAChC,gEAAgE;AAChE,eAA0C,cAAc;IAExD,IAAI;QACF,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;KAClC;IAAC,OAAO,KAAK,EAAE;QACd,MAAM,QAAQ,CACZ,YAAY,EACZ,GAAG,WAAW,KAAK,oCAAoC,CAAC,KAAK,CAAC,GAAG,CAClE,CAAC;KACH;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAc;IAC7C,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;AACJ,CAAC","sourcesContent":["import type { Struct } from '@metamask/superstruct';\nimport { assert as assertSuperstruct } from '@metamask/superstruct';\n\nimport { getErrorMessage } from './errors';\n\nexport type AssertionErrorConstructor =\n  | (new (args: { message: string }) => Error)\n  | ((args: { message: string }) => Error);\n\n/**\n * Check if a value is a constructor, i.e., a function that can be called with\n * the `new` keyword.\n *\n * @param fn - The value to check.\n * @returns `true` if the value is a constructor, or `false` otherwise.\n */\nfunction isConstructable(\n  fn: AssertionErrorConstructor,\n): fn is new (args: { message: string }) => Error {\n  /* istanbul ignore next */\n  return Boolean(typeof fn?.prototype?.constructor?.name === 'string');\n}\n\n/**\n * Attempts to obtain the message from a possible error object. If it is\n * possible to do so, any trailing period will be removed from the message;\n * otherwise an empty string is returned.\n *\n * @param error - The error object to get the message from.\n * @returns The message without any trailing period if `error` is an object\n * with a `message` property; the string version of `error` without any trailing\n * period if it is not `undefined` or `null`; otherwise an empty string.\n */\nfunction getErrorMessageWithoutTrailingPeriod(error: unknown): string {\n  // We'll add our own period.\n  return getErrorMessage(error).replace(/\\.$/u, '');\n}\n\n/**\n * Initialise an {@link AssertionErrorConstructor} error.\n *\n * @param ErrorWrapper - The error class to use.\n * @param message - The error message.\n * @returns The error object.\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction getError(ErrorWrapper: AssertionErrorConstructor, message: string) {\n  if (isConstructable(ErrorWrapper)) {\n    return new ErrorWrapper({\n      message,\n    });\n  }\n  return ErrorWrapper({\n    message,\n  });\n}\n\n/**\n * The default error class that is thrown if an assertion fails.\n */\nexport class AssertionError extends Error {\n  readonly code = 'ERR_ASSERTION';\n\n  constructor(options: { message: string }) {\n    super(options.message);\n  }\n}\n\n/**\n * Same as Node.js assert.\n * If the value is falsy, throws an error, does nothing otherwise.\n *\n * @throws {@link AssertionError} If value is falsy.\n * @param value - The test that should be truthy to pass.\n * @param message - Message to be passed to {@link AssertionError} or an\n * {@link Error} instance to throw.\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}. If a custom error class is provided for\n * the `message` argument, this argument is ignored.\n */\nexport function assert(\n  value: any,\n  message: string | Error = 'Assertion failed.',\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  ErrorWrapper: AssertionErrorConstructor = AssertionError,\n): asserts value {\n  if (!value) {\n    if (message instanceof Error) {\n      throw message;\n    }\n\n    throw getError(ErrorWrapper, message);\n  }\n}\n\n/**\n * Assert a value against a Superstruct struct.\n *\n * @param value - The value to validate.\n * @param struct - The struct to validate against.\n * @param errorPrefix - A prefix to add to the error message. Defaults to\n * \"Assertion failed\".\n * @param ErrorWrapper - The error class to throw if the assertion fails.\n * Defaults to {@link AssertionError}.\n * @throws If the value is not valid.\n */\nexport function assertStruct<Type, Schema>(\n  value: unknown,\n  struct: Struct<Type, Schema>,\n  errorPrefix = 'Assertion failed',\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  ErrorWrapper: AssertionErrorConstructor = AssertionError,\n): asserts value is Type {\n  try {\n    assertSuperstruct(value, struct);\n  } catch (error) {\n    throw getError(\n      ErrorWrapper,\n      `${errorPrefix}: ${getErrorMessageWithoutTrailingPeriod(error)}.`,\n    );\n  }\n}\n\n/**\n * Use in the default case of a switch that you want to be fully exhaustive.\n * Using this function forces the compiler to enforce exhaustivity during\n * compile-time.\n *\n * @example\n * ```\n * const number = 1;\n * switch (number) {\n *   case 0:\n *     ...\n *   case 1:\n *     ...\n *   default:\n *     assertExhaustive(snapPrefix);\n * }\n * ```\n * @param _object - The object on which the switch is being operated.\n */\nexport function assertExhaustive(_object: never): never {\n  throw new Error(\n    'Invalid branch reached. Should be detected during compilation.',\n  );\n}\n"]}