"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.brandedNumberType = exports.brandedStringType = exports.brandErased = exports.brandOpaque = exports.brand = exports.fromErased = exports.extractFromOpaque = exports.BrandedType = exports.ErasedType = void 0;
const typebox_1 = require("@sinclair/typebox");
/**
 * Helper for {@link Erased}.
 * This is split out into its own as that's the only way to:
 * - have doc comments for the member.
 * - make the member protected (so you don't accidentally try and read it).
 * - get nominal typing (so types produced without using this class can never be assignable to it).
 *
 * See `InternalTypes.MakeNominal` for some more details.
 *
 * Do not use this class with `instanceof`: this will always be false at runtime,
 * but the compiler may think it's true in some cases.
 *
 * @sealed
 * @internal
 */
class ErasedType {
    /**
     * This class should never exist at runtime, so make it un-constructable.
     */
    constructor() { }
}
exports.ErasedType = ErasedType;
/**
 * Helper for {@link Brand}.
 * This is split out into its own as that's the only way to:
 * - have doc comments for the member.
 * - make the member protected (so you don't accidentally try and read it).
 * - get nominal typing (so types produced without using this class can never be assignable to it).
 * - allow use as {@link Opaque} branded type (not assignable to `ValueType`, but captures `ValueType`).
 *
 * See `InternalTypes.MakeNominal` for some more details.
 *
 * Do not use this class with `instanceof`: this will always be false at runtime,
 * but the compiler may think it's true in some cases.
 *
 * @remarks
 * This is covariant over ValueType.
 * This is suitable for when ValueType is immutable (like string or number),
 * which is the common use-case for branding.
 *
 * @sealed
 * @internal
 */
class BrandedType {
    /**
     * This class should never exist at runtime, so make it un-constructable.
     */
    constructor() { }
}
exports.BrandedType = BrandedType;
/**
 * Converts a {@link Opaque} handle to the underlying branded type.
 *
 * It is assumed that only code that produces these "opaque" handles does this conversion,
 * allowing these handles to be considered opaque.
 * @internal
 */
function extractFromOpaque(value) {
    return value;
}
exports.extractFromOpaque = extractFromOpaque;
/**
 * Converts a {@link Erased} handle to the underlying branded type.
 *
 * It is assumed that only code that produces these "opaque" handles does this conversion,
 * allowing these handles to be considered opaque.
 * @internal
 */
function fromErased(value) {
    return value;
}
exports.fromErased = fromErased;
/**
 * Adds a type {@link Brand} to a value.
 *
 * Only do this when specifically allowed by the requirements of the type being converted to.
 * @internal
 */
function brand(value) {
    return value;
}
exports.brand = brand;
/**
 * Adds a type {@link Brand} to a value, returning it as a {@link Opaque} handle.
 *
 * Only do this when specifically allowed by the requirements of the type being converted to.
 * @internal
 */
function brandOpaque(value) {
    return value;
}
exports.brandOpaque = brandOpaque;
/**
 * Adds a type {@link Brand} to a value, returning it as a {@link Erased} handle.
 *
 * Only do this when specifically allowed by the requirements of the type being converted to.
 * @internal
 */
function brandErased(value) {
    return value;
}
exports.brandErased = brandErased;
/**
 * Create a TypeBox string schema for a branded string type.
 * This only validates that the value is a string,
 * and not that it came from the correct branded type (that information is lost when serialized).
 */
function brandedStringType() {
    // This could use:
    // return TypeSystem.CreateType<T>(name, (options, value) => typeof value === "string")();
    // Since there isn't any useful custom validation to do and
    // TUnsafe is documented as unsupported in `typebox/compiler`,
    // opt for the compile time behavior like the above, but the runtime behavior of the built in string type.
    return typebox_1.Type.String();
}
exports.brandedStringType = brandedStringType;
function brandedNumberType(options) {
    // See comments on `brandedStringType`.
    return typebox_1.Type.Number(options);
}
exports.brandedNumberType = brandedNumberType;
//# sourceMappingURL=brand.js.map