"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: all[name]
    });
}
_export(exports, {
    AssertionError: function() {
        return AssertionError;
    },
    assert: function() {
        return assert;
    },
    assertStruct: function() {
        return assertStruct;
    },
    assertExhaustive: function() {
        return assertExhaustive;
    }
});
const _superstruct = require("superstruct");
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
/**
 * Type guard for determining whether the given value is an error object with a
 * `message` property, such as an instance of Error.
 *
 * @param error - The object to check.
 * @returns True or false, depending on the result.
 */ function isErrorWithMessage(error) {
    return typeof error === 'object' && error !== null && 'message' in error;
}
/**
 * Check if a value is a constructor, i.e., a function that can be called with
 * the `new` keyword.
 *
 * @param fn - The value to check.
 * @returns `true` if the value is a constructor, or `false` otherwise.
 */ function isConstructable(fn) {
    /* istanbul ignore next */ return Boolean(typeof fn?.prototype?.constructor?.name === 'string');
}
/**
 * Get the error message from an unknown error object. If the error object has
 * a `message` property, that property is returned. Otherwise, the stringified
 * error object is returned.
 *
 * @param error - The error object to get the message from.
 * @returns The error message.
 */ function getErrorMessage(error) {
    const message = isErrorWithMessage(error) ? error.message : String(error);
    // If the error ends with a period, remove it, as we'll add our own period.
    if (message.endsWith('.')) {
        return message.slice(0, -1);
    }
    return message;
}
/**
 * Initialise an {@link AssertionErrorConstructor} error.
 *
 * @param ErrorWrapper - The error class to use.
 * @param message - The error message.
 * @returns The error object.
 */ // eslint-disable-next-line @typescript-eslint/naming-convention
function getError(ErrorWrapper, message) {
    if (isConstructable(ErrorWrapper)) {
        return new ErrorWrapper({
            message
        });
    }
    return ErrorWrapper({
        message
    });
}
class AssertionError extends Error {
    constructor(options){
        super(options.message);
        _define_property(this, "code", 'ERR_ASSERTION');
    }
}
function assert(value, message = 'Assertion failed.', // eslint-disable-next-line @typescript-eslint/naming-convention
ErrorWrapper = AssertionError) {
    if (!value) {
        if (message instanceof Error) {
            throw message;
        }
        throw getError(ErrorWrapper, message);
    }
}
function assertStruct(value, struct, errorPrefix = 'Assertion failed', // eslint-disable-next-line @typescript-eslint/naming-convention
ErrorWrapper = AssertionError) {
    try {
        (0, _superstruct.assert)(value, struct);
    } catch (error) {
        throw getError(ErrorWrapper, `${errorPrefix}: ${getErrorMessage(error)}.`);
    }
}
function assertExhaustive(_object) {
    throw new Error('Invalid branch reached. Should be detected during compilation.');
}

//# sourceMappingURL=assert.js.map