import type { AppError } from '../error/error.util.js';
/**
 * Function returns a tuple of [err, output].
 *
 * If ERR is returned, it indicates that validation has failed.
 * If ERR is null - validation has succeeded.
 *
 * Regardless of the Error, ValidationFunction always returns the output item.
 *
 * Output item may be transformed or not, depending on the implementation.
 *
 * ValidationFunction may mutate the input item or not,
 * depending on the implementation.
 *
 * @experimental
 */
export type ValidationFunction<OUT, ERR extends AppError> = (input: unknown, opt?: ValidationFunctionOptions) => ValidationFunctionResult<OUT, ERR>;
export type ValidationFunctionResult<OUT, ERR extends AppError> = [err: ERR | null, output: OUT];
export interface ValidationFunctionOptions {
    /**
     * Defaults to undefined.
     *
     * Undefined means that it's up for the underlying validation library (implementation)
     * to mutate or not.
     * E.g joi and zod would deep-clone, while ajv would mutate.
     *
     * False means that the ValidationFunction IS NOT ALLOWED to mutate the input.
     * If set to true - the ValidationFunction HAS TO mutate the input
     * if it needs to apply transformations, such as:
     * - stripping unknown properties
     * - converting types (e.g. string to number)
     * - applying transformations (which as string trim, toLowerCase, etc)
     */
    mutateInput?: boolean;
    /**
     * E.g User
     * Used for error message printing.
     */
    inputName?: string;
    /**
     * E.g `12345678` (user id).
     * Used for error message printing.
     */
    inputId?: string;
}
